SOM map full understanding - som

I have some enqueries to fully understand how SOM maps work, if you check this SOM map:
1 - Why there are some points in the map that doesn’t have any label (A, B or C)?
2 - I understand that in each node there are more than 1 elements. How many elements of a type must be in node to see its label in in the map?
3 - What is the meaning of the gray colors? Does black mean that there are a lot of points that match that cell? Or does it mean that there is a big distance between that cell and the near one?
4 - Why there is not any label (A, B or C) in any black cell? I realized later than this map is of size 10 x 5, and the labels can only be located at the points. Is that correct?
Thank you in advance!!

It's not a SOM map. it's a U-Matrix, which shows the distances between nodes. This will explain why there is a gap between every node and every other node. In the U-Matrix, the shade of the hexagon in the middle is lighter when the two nodes are near one another and darker when they are further apart. See http://users.ics.aalto.fi/jhollmen/dippa/node24.html for more info.
The number of labels in each cell depends on the 'mode'. I'm not sure what implementation you're using but the modes for SOM Toolbox are:
% From https://github.com/ilarinieminen/SOM-Toolbox/blob/master/som/som_autolabel.m
% The modes:
% 'add': all labels from sFrom are added to sTo (even multiple
% copies of same)
% 'add1': only one instance of each label is kept
% 'freq': only one instance of each label is kept and '(#)', where
% # is the frequency of the label, is added to the end of
% the label. Labels are ordered according to frequency.
% 'vote': only the label with most instances is kept

Related

Reducing the area of the voronoi cells and determining the coordinates of new vertices

I have written a MATLAB code to create the figure attached using the voronoi. My region of interest is the red circle. Hence the seeds for voronoi were kept within the region.
Idea: One approach would be to use a homothetic transformation of the Voronoi cell C{k} about the corresponding point X(k,:), with a ratio R such as 0 < R < 1. The shape of the cells—the number of corners and their associated angles—will be preserved, and the areas will be reduced proportionally (i.e. by a factor R2, and not by a constant value).
Please note that this will "destroy" your cells, because the reduced Voronoi cells will not share anymore vertices/edges, thus the [V,C] representation doesn't work anymore as it is. Also, the distances between what were once common edges will depend on the areas of the original cells (bigger cells, bigger distances between adjacent edges).
Transformation example for 2 2D points:
A = [1,2]; %'Center'
B = [10,1]; %'To be transformed'
R = 0.8; %'Transformation ratio'
trB = A + R*(B-A); %'Transformed'
couldn't follow your implementation of CST-link's idea, but here is one that works (i tested it in matlab, but not yet in abaqus, the code it spits out looks like abaqus should be happy with it)
rng(0);
x=rand(40,2);
plot(x(:,1),x(:,2),'x')
[v,c]=voronoin(x);
fact=0.9;
for i=1:length(c)
cur_cell=c{i};
coords=v(cur_cell,:);
if isfinite(coords)
%fact=somefunctionofarea?;
centre=x(i,:); % i used the voronoi seeds as my centres
coords=bsxfun(#minus,coords,centre); %move everything to a local coord sys centred on the seed point
[theta,rho] = cart2pol(coords(:,1),coords(:,2));
[xnew, ynew]= pol2cart(theta,rho*fact);
xnew=xnew+centre(1); % put back in real coords.
ynew=ynew+centre(2);
xnew2=circshift(xnew,1);
ynew2=circshift(ynew,1);
fprintf('s1.Line(point1=(%f,%f),point2=(%f,%f))\n',...
[xnew, ynew, xnew2,ynew2]');
line(xnew,ynew); %testing purposes - doesn't plot last side in matlab
end
end
Having seen the results of this one, i think you will need a different way factor to shrink your sides. either to subtract a fixed area or some other formula.

How to find all the blue pixels and the location of the two boundaries in blue pixels?

I want to find per column the first and last blue pixels and them find the other boundary ( first and last blue pixel rows) inside this rows achieved before.
I made the alterations based on the previous answeers, but now I have this error when it tries to find the bif_first and last: Subscripted assignment dimension mismatch. bif_first2(2,z)=find(dx(:,z)==1,2,'first');
What is wrong? Please see my code below:
rgbImage_blue=zeros(size(movingRegistered));
lumen_first=zeros(1,size(movingRegistered,2)); lumen_last=zeros(1,size(movingRegistered,2)); bif_first=zeros(1,size(movingRegistered,2)); bif_last=zeros(1,size(movingRegistered,2)); bif_last2=zeros(2,size(movingRegistered,2)); bif_first2=zeros(2,size(movingRegistered,2));
blue=cat(3,0,0,255);
ix=all(bsxfun(#eq,movingRegistered,blue),3);% find all the blue pixels, and put them at 1 % logical array of where blue pixels are dx=[zeros(1,size(movingRegistered,2));diff(ix)]; % zeros to make the same number of columns and rows % the difference by row for all columns
nTops=sum(dx==1); % the transitions to blue
nBots=sum(dx==-1); % and from blue... % see if are consistent; if not, something's not right in image
if(nTops~=nBots), error('Mismatch in Top/Bottom'),end
for z=1:1:size(movingRegistered,2);
if nTops(1,z)==2; bifurcation=false;lumen=true; %only existis two boundaries no bifurcation
lumen_first(1,z)=find(ix(:,z)==1,1,'first');
lumen_last(1,z)=find(ix(:,z)==1,1,'last');
end
if nTops(1,z)>2;
bifurcation=true;
lumen_first(1,z)=find(ix(:,z)==1,1,'first');
lumen_last(1,z)=find(ix(:,z)==1,1,'last');
bif_first2(2,z)=find(dx(:,z)==1,2,'first');
bif_first(1,z)=bif_first2(2,z);
bif_last2(2,z)=find(dx(:,z)==1,2,'last');
bif_last(1,z)=bif_last2(2,z);
end
end
Your problem is you are comparing a n*m*3 image with a 3*1 vector. This operation is not defined.
Use this code:
blue=cat(3,0,0,250)
ix=all(bsxfun(#eq,movingRegistered,blue),3)
Images in Matlab use the third dimension for color, that's why I created blue to be a 1*1*3 vector. Now this vector is compared to the image, using bsxfun to expand the vector to match the image size. This operation compares each color channel individually, so all is used to collect the data for all three channels.

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.

in matlab, find 3D neighbourhood

I have a volume (3D matrix) that has undergone a segmentation process. Most of the volume consist of NaNs (or zeros), except regions that have passed some criteria (see picture). I need to know how large each remaining segment is in number of voxels and how is their distribution on the 2D planes (xy, xz, yz). Is there anything in matlab that can help me do this in an efficient way rather than direct search? The volume can be rather large. For ex. in the attached picture there is one segment in yellowish/brownish colour of 7 voxels and extends more vertically than in xy.
Thanks in advance.
The most convenient solution is to use REGIONPROPS. In your example:
stats = regionprops(image, 'area', 'centroid')
For every feature, there is an entry in the structure stats with the area (i.e. # of voxels) and the centroid.
I think that what you are looking for is called bwlabeln. It allows you to find blobs in 3D space, just like bwlabel does in 2D. Afterwards, you can use regionprops to find out the properties of the data.
Taken directly from help:
bwlabeln Label connected components in binary image.
L = bwlabeln(BW) returns a label matrix, L, containing labels for the
connected components in BW. BW can have any dimension; L is the same
size as BW. The elements of L are integer values greater than or equal
to 0. The pixels labeled 0 are the background. The pixels labeled 1
make up one object, the pixels labeled 2 make up a second object, and
so on. The default connectivity is 8 for two dimensions, 26 for three
dimensions, and CONNDEF(NDIMS(BW),'maximal') for higher dimensions.

How to plot 2D data with different colors and markers

Im faced with a problem where i need to plot a two dimensional data with different colors and markers.
We are given with 2 array, namely points (n x 2 dimension) and Label (n x 1 dimension). Im not sure about the number of unique values in the Label array but maximum could be 10. I would like to plot the points with different color and markers based on its corresponding Label value.
Can any one help me in this regard
Use gscatter, which does a scatter plot, using a group (Label in your case) to plot in different colours/makers.
GSCATTER(X,Y,G,CLR,SYM,SIZ) specifies the colors, markers, and
size to use. CLR is either a string of color specifications or
a three-column matrix of color specifications. SYM is a string
of marker specifications. Type "help plot" for more information.
For example, if SYM='o+x', the first group will be plotted with a
circle, the second with plus, and the third with x. SIZ is a
marker size to use for all plots. By default, the marker is '.'.
So you can specify colours like 'rgcmykwb' to do red for the first group, green for the second, etc or [] just to have Matlab sort it out.
By default Matlab uses the same marker for each group, so you need to specify what markers you want to be used for each group. If you do '.ox+*sdv^<>ph' you'll just cycle along all the markers that Matlab has.
n=50;
% make nx2 matrix of random points.
points = random('unif',0,1,n,2);
% make nx1 matrix of random labels from {1,2,...,5}
labels=round(random('unif',1,5,n,1));
% plot. Let Matlab sort out the colours and we will specify markers.
gscatter(points(:,1),points(:,2),labels,[],'ox+*sdv^<>ph.')
It looks a bit like this: