Given a discrete image, e.g.:
how can one find the local minima/maxima locations?
EDIT:
Maximum and minimum in terms of derivative, not absolute max/min. In the example below the results should be two lines at the bottom, and some local peaks at the top.
Note that deriving is not that simple since the zero locations falls between pixels, and zero crossing in a 2d image is more complected than a 1d signal.
Thanks,
Find the linear index of the max/min (second output) and then use ind2sub to get the row and column coordinates.
%Assuming your image is stored in matrix I
[Vmax, Imax] = max(I(:));
[Rmax, Cmax] = ind2sub(size(I), Imax);
[Vmin, Imin] = min(I(:));
[Rmin, Cmin] = ind2sub(size(I), Imin);
Related
I suppose this is not something difficult but i wonder if there is any function or any optimal way.
Consider that after an image process i have a matrix-image with 0 everywhere and 1 at the contour.
Now i want to find the x y along that contour line
The important is that eg [ x(2) y(2) ] should be the next pixel to [x(1) y(1)]
I have used this:
[c h]=contour(image,1)
x=c(1,:)
y=c(2,:)
But the result is not very good and it gives some noise points which is very bad (and for some reason it appears mirrored)
If you have the image processing toolbox, I highly suggest using bwperim which returns a logical image where true is a perimeter or contour point and false otherwise.... not to mention that it's faster.
Try doing:
bw = bwperim(image == 1); % image == 1 to ensure binary
[y, x] = find(bw);
The first line of code finds an image that only contains contour points, and we can use find after that on the result to find the row and column locations. Here y represents the row and x represents the column locations.
If you desire that the contour is ordered, then use the bwtraceboundary function instead. However, this will require that you specify an initial contour point prior to running the function.
An easy way to do this would be to find any non-zero point along the contour of your object. You could use bwperim first and sample any point from here. Choosing just any point may not give you an actual contour point.
Therefore:
bw = bwperim(image == 1); % image == 1 to ensure binary
[y, x] = find(bw, 1); % Find the first contour point
ctr = bwtraceboundary(image == 1, [y, x], 'SE');
'SE' is the direction of where to look first given the initial contour point. Here I've chosen south east. This will produce a N x 2 matrix where the first column contains the rows and second column contains the columns of the ordered contour points starting at the initial position provided by y and x.
I have posted my complete solution to help other people:
Problem:
I have a grayscale image and i want to find the coordinates X Y in order along the contour .
Solution:
Set a threshold for black and white and make the image binary (optional)
`image=image>0.5 %This is optional but some may found it usefull`
Find the Start Point:
[yStart xStart]=find(image,1);
This will scan the image column by column from left to right and up to down and will return the first non zero pixel. So this will return the 'left-est up' pixel of the image. Remember, X is the column and Y is the row. Zero is at the top-left corner!
Find the contour:
contour=bwtraceboundary(image, [yStart, xStart],'NE');
or
contour = bwtraceboundary(image,[yStart xStart],'NE',8,Inf,'clockwise');
NE is the initial direction (NorthEast)
x=contour(:,2)
y=contour(:,1)
If the point [yStart xStart] is not on the contour of an image this will not work !
If you plot (x,y) that will be mirrored. This is because the zero at the coordinate system is at the top left corner of the image and not at the bottom left. To do it properly you can do this:
y=-y
y=y+abs(min(y))+1 % +1 is to avoid y=0
I'm trying to find the closes point to an area in an image with Matlab:
consider this example code:
myimg = rgb2gray(imread('tissue.png')); %load grayscale example image of cells
BW=bwareaopen(myimg<150,10); %only look at dark pixels, remove small objects
BW=bwlabel(imfill(BW,'holes')) %fill holes of structures, label structures
figure;
imagesc(BW); %display image
I'd like to find the closest point of the closest structure to a point e.g. [0,0]. My approach so far is to get all centroids of all connected structures, then loop through all of them to find the closest one (inaccurate and inefficient).
If you just want to find a single closest point, you can use bwdist with a second output argument. This will give you a matrix which at each point contains the linear index of the closest non-zero point of the input image. You then just need to select the index corresponding to the point you are interested in. The input image to bwdist should be binary, so in your case you could try something like
% Make the image binary
binaryimage = BW > 0;
% Get the linear indices of the closest points
[~, idx] = bwdist(binaryimage);
% Find the linear index for point (3, 2)
x = 3;
y = 2;
pointindex = sub2ind(size(binaryimage), y, x);
% Find the index of the closet point from the segmentation
closestpointindex = idx(pointindex);
% Get coordinates of the closest point
[yc, xc] = ind2sub(size(binaryimage), closestpointindex);
This will give you the coordinates (xc, yc) and the matrix index (closestpointindex) of the pixel with a non-zero value in the binary image which is closest to the point (x,y), where x and y are Matlab indices, remembering that Matlab indices start at 1 and rows are first, i.e. BW(y,x).
I have a binary image and have found the minimum distance connecting two nearby regions of interest/connected components using
min(min(pdist2(CCstats(1).PixelList,CCstats(2).PixelList)))
I also need to get the coordinates of these ends of this distance/the most adjacent pixels between these 2 regions of interest
I plan on drawing a line along this distance. I was going to use something like:
x=linspace(coord1(1), coord2(1),1000);
y=linspace(coord1(2), coord2(2),1000);
index=sub2ind(size(image),round(y),round(x));
image(index)=1;
Any suggestions for how to find these coordinates?
You will want the second output of min (combined with ind2sub) to determine the row/column of the pdist2 matrix that corresponds to the minimum distance.
distances = pdist2(CCstats(1).PixelList, CCstats(2).PixelList);
[mindist, minind] = min(distances(:));
%// Now convert this linear index into index1/index2 into your pixel lists
[index1, index2] = ind2sub(size(distances), minind);
%// Now grab the coordinates using these index values
coord1 = CCstats(1).PixelList(index1,:);
coord2 = CCstats(2).PixelList(index2,:);
I am trying to implement brain tumor segmentation on 3D brain MRI(.mha data type).
After preliminary segmentation, I am applying 26-neighbor connected component algorithm(using bwconncomp) to obtain the largest connected component by obtaining the component with the largest volume, following which I need to calculate the centroid of the resultant component.
I am not sure if my method of calculating the largest connected component and the centroid is correct, because the centroid obtained and its nearby voxels all have value 0.
Also I am having confusion with the representation of 3D voxel coordinates. For eg. if centroid=(x,y,z), does it correspond to x=row,y=column and z=2D slice?
Any help would be appreciated. Below is my code with the relevant part.
CC=bwconncomp(Ibin,26); %Input Black & White 3D data of size 240x240x155
Pixelid=regionprops(CC,'PixelIdxList');
[prow pcol]=size(Pixelid);
maxval=numel(Pixelid(1).PixelIdxList);
index=1;
for i=1:prow
number=numel([Pixelid(i).PixelIdxList]);
if (number>maxval) %calculating the component with max number of voxels
maxval=number;
index=i;
end
end
for i=1:prow
if i~=index
Ibin(Pixelid(i).PixelIdxList)=0;
end
end
CC1=bwconncomp(Ibin,26);
Cent=regionprops(CC1,'Centroid');
I changed your code to the following:
CC=bwconncomp(Ibin,26);
PixelIdxList = CC.PixelIdxList;
maxval = numel(PixelIdxList{1});
index = 1;
for ii = 1:length(PixelIdxList)
number = numel(PixelIdxList{ii});
if number > maxval
maxval = number;
index = ii;
end
end
[y,x,z] = ind2sub(size(Ibin),PixelIdxList{index})
centroid = [mean(x), mean(y), mean(z)];
bwconncomp already gives you a PixelIdxList so you don't have to use regionprops. The PixelIdxList lists pixels by their linear indices, so you have to convert them into subscripts to get x, y, and z coordinates. The first dimension in MATLAB matrix represents y coordinates, and second dimension represents x, while the third dimension represents z. Centroid is calculated by taking the mean x, y, and z coordinates of all the pixels contained in the object.
In MATLAB I'm dropping points into the square [0,1]X[0,1] uniformly at random. I'm then placing an edge between two points if the distance between the two points is less than 0.25. The code to do this (and plot the resulting graph is below).
num_Rx = 50
Rx_positions = rand(num_Rx,2);
%Generate edges between pairs of within norm of 0.25.
adj_matrix = zeros(num_Rx, num_Rx);
for i=1:num_Rx
for j=i+1:num_Rx
dist = norm(Rx_positions(i,:) - Rx_positions(j,:));
if dist < 0.25;
adj_matrix(i,j) = 1;
end
end
end
figure
gplot(adj_matrix, Rx_positions)
i.e. this is an undirected graph, with all edge weights equal to 1.
To find the diameter I want to call graphallshortestpaths() (http://www.mathworks.co.uk/help/bioinfo/ref/graphallshortestpaths.html), and take the maximum value returned (the diameter is the longest shortest path).
However, I'm having difficulty calling this function - I can't figure out how to make a call like the examples, from my adjacency matrix and/or my list of node positions. Specifically I don't understand any of the examples, how the matlab code given corresponds to the data presented.
How would I go about doing this.
It appears that all you're missing is converting your adjacency matrix to a sparse matrix. This should give you what you're looking for:
adj_sparse = sparse(adj_matrix);
distances = graphallshortestpaths(adj_sparse);
% if you don't care which nodes produce the
% longest shortest path, omit long_ind & long_sub
[diameter, long_ind] = max(distances(:));
long_sub = ind2sub(size(distances), long_ind);