Can active contour segment the image into different regions? - matlab

When I use the activecontour method in matlab, it seems that I can only segment the image into foreground and background, but I want to segment my MRI image into multiple regions, can I use activeconter in this case, or do I need to use other methods such as watershed?

You can start with multiple seed contours to segment multiple regions but watershed might work better depending on how much different structures are overlapping.

Related

Is it possible to join regions of an image in Matlab?

I have an image with some regions that I would like to join, would this be possible?
The image is the following:
I'm using regionprops to count that regions as well, and I want that the result of this image is 2 regions instead of 4 that actually are, more or less like that:
(this image is an example, in order to explain it better).
In fact, I want to join the regions that are near each other.
Would this be possible? How?
I would first convolve
(conv2 -- https://www.mathworks.com/help/matlab/ref/conv2.html)
the original image with a 2D Gaussian in order to smooth the image. In doing so, the edges of the regions will be broadened and run into one another -- effectively making multiple regions that are close together bleed into one region. You will have to play with the 2D Gaussian by varying your sigma in order to achieve the desired smoothness.
Once the image is filtered/smoothed, you can use your original algorithm within regionprops to count the number or regions.
Let me know if that helps or if I am being unclear.

Increase size of individual connected component in a binary image (BW) when using regionprops

I am using imregionalmax to create a binary image BW that identifies the regional maxima in my image.
Next I want to use regionprops with property WeightedCentroid to identify the coordinates of the centroid centers in the image. However, imregionalmax returns a binary image with very small connected components, which need to be increased in dimension to enable regionprops to weigh the centroid properly.
Possible solutions:
I believe the ideal situation would be to interrupt the regionprops operation at each iteration, and simply increase the size of the current connected component that it is working with by adding a couple of pixels in height and width to it.
In case this is not possible, a work around could be to split BW into an image stack with only a single connected component in each slice, expand each component by some pixels, and run regionprops individually on each image slice. This does not seem like a efficient way of solving this though.
Is there another more efficient way, and how would I implement that?
** I am aware that one way of increasing the connected components in BW is to use imdilate, but this will lead to unconnected components becoming connected.
** Another option is to use bwmorph with property thicken, which performs very well, however in a case where multiple components are close together, the size cannot be increased in one direction and reduce the performance of WeightedCentroid.
You cannot increase measurement accuracy by extending what you want to measure...
Centroid is simply the average of all region coordinates.
WeightedCentroid only takes intensities into account in case you don't have a binary image.
If you increase your object by whatever algorithm you like you risk shifting your centroid away from its true position!

Image Segmentation Using Prior Shape Information Matlab

I have a series of medical images from which I am attempting to segment out and analyze the ECG tracings in Matlab (the green, spiking line in the image below):
I have so far been successful in doing this on a small set of images using color thresholding and region properties. My problem is that almost all aspects of this feature of interest can change depending on the manufacturer of the machine used to produce the images and the behavior of the user operating it (over which I have 0 control).
Potentially differing attributes include line position in the image (which can change to be almost anywhere in the image), amplitude, frequency, and even color (which can be changed to match the color of the large white surface under the line in the above image). This makes it extremely difficult to create a robust segmentation solution for all images relying only on "simple" methods (color segmentation, region properties, edge detection etc).
Would it be straight forward to train a classifier to identify the general shape of this line and segment it out? Alternatively, is there another way to search and segment an image using prior shape information?
If you are currently applying an arbitrary threshold, you can look at various technique for dynamic thresholding (here a technique that applies the concept on edge detection).
What you could also try is to threshold on a different representation of the image, such as HSL and HSV (as I am assuming you are thresholding on the RGB values)
You may use a classifier and active contour model to segment the desired region. An example can be found here: http://pratondo.staff.telkomuniversity.ac.id/2016/01/14/robust-edge-stop-functions-for-edge-based-active-contour-models-in-medical-image-segmentation/

matlab: remove small edges and simplify an histology image

I have an image like this:
What I want to do is to find the outer edge of this cell and the inner edge in the cell between the two parts of different colors.
But this image contains to much detail I think, and is there any way to simplify this image, remove those small edges and find the edges I want?
I have tried the edge function provided by matlab. But it can only find the outer edge and disturbed by those detailed edges.
This is a very challenging work due to the ambiguous boundaries and tiny difference between red and green intensities. If you want to implement the segmentation very precisely and meet some medical requirements, Shai's k-means plus graph cuts may be one of the very few options (EM algorithm may be an alternative). If you have a large database that has many similar images, some machine learning methods might help. Otherwise, I just wrote a very simple code to roughly extract the internal red region for you. The boundary is not that accurate since some of the green regions are also included.
I1=I;
I=rgb2hsv(I);
I=I(:,:,1); % the channel with relatively large margin between green and red
I=I.*(I<0.25);
I=imdilate(I, true(5));
% I=imfill(I,'holes'); depends on what is your definition of the inner boundary
bw=bwconncomp(I);
ar=bw.PixelIdxList;
% find the largest labeled area,
n=0;
for i=1:length(ar)
if length(ar{i})>n
n=length(ar{i});
num=i;
end
end
bw1=bwlabel(I);
bwfinal(:,:,1)=(bw1==num).*double(I1(:,:,1));
bwfinal(:,:,2)=(bw1==num).*double(I1(:,:,2));
bwfinal(:,:,3)=(bw1==num).*double(I1(:,:,3));
bwfinal=uint8(bwfinal);
imshow(bwfinal)
It seems to me you have three dominant colors in the image:
1. blue-ish background (but also present inside cell as "noise")
2. grenn-ish one part of cell
3. red-ish - second part of cell
If these three colors are distinct enough, you may try and segment the image using k-means and Graph cuts.
First stage - use k-means to associate each pixels with one of three dominant colors. Apply k-means to the colors of the image (each pixel is a 3-vector in your chosen color space). Run k-means with k=3, keep for each pixel its distance to centroids.
Second stage - separate cell from background. Do a binary segmentation using graph-cut. The data cost for each pixel is either the distance to the background color (if pixel is labeled "background"), or the minimal distance to the other two colors (if pixel is labeled "foreground"). Use image contrast to set the pair-wise weights for the smoothness term.
Third stage - separate the two parts of the cell. Again do a binary segmentation using graph-cut but this time work only on pixels marked as "cell" in the previous stage. The data term for pixels that the k-means assigned to background but are labeled as cell should be zero for all labels (these are the "noise" pixels inside the cell).
You may find my matlab wrapper for graph-cuts useful for this task.

5-dimensional plotting in matlab for classification

I want to create a 5 dimensional plotting in matlab. I have two files in my workspace. one is data(150*4). In this file, I have 150 data and each has 4 features. Since I want to classify them, I have another file called "labels" (150*1) that includes a label for each data in data files. In other words the label are the class of data and I have 3 class: 1,2,3
I want to plot this classification, but i can't...
Naris
You need to think about what kind of plot you want to see. 5 dimensions are difficult to visualize, unless of course, your hyper-dimensional monitor is working. Mine never came back from the repair shop. (That should teach me for sending it out.)
Seriously, 5 dimensional data really can be difficult to visualize. The usual solution is to plot points in a 2-d space (the screen coordinates of a figure, for example. This is what plot essentially does.) Then use various attributes of the points plotted to show the other three dimensions. This is what Chernoff faces do for you. If you have the stats toolbox, then it looks like glyphplot will help you out. Or you can plot in 3-d, then use two attributes to show the other two dimensions.
Another idea is to plot points in 2-d to show two of the dimensions, then use color to indicate the other three dimensions. Thus, the RGB assigned to that marker will be defined by the other three dimensions. Of course, that means you must be able to visualize what the RGB coordinates of a color represent, so you need to understand color as it is represented in an RGB space.
You can use scatter3 to plot your data, using three features of data as dimensions, the fourth as color, and the class as different markers
figure,hold on
markerList = 'o*+';
for iClass = 1:nClasses
classIdx = dataClass==iClass;
scatter3(data(classIdx,1),data(classIdx,2),data(classIdx,3),[],data(classIdx,4),...
'marker',markerList(iClass));
end
When you use color to represent one of the features, I suggest to use a good colormap, such as pmkmp from the Matlab File Exchange instead of the default jet.
Alternatively, you can use e.g. mdscale to transform your higher-dimensional data to 2D for standard plotting.
There's a model called SOM (Self-organizing Maps) which builds a 2-D image of a multidimensional space.