Centroid calculation for a connected component in 3D volume using Matlab - matlab

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.

Related

Find closest point of labelled area to a point in an image with Matlab

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).

Define points within a radius for post analysis

I'm new to matlab an I'm trying for figure something out. I have a matrix that is 50x50. It represents data I recorded behind a turbine. The turbine is essentially placed in the center of this plane at the point (25,25). It has a radius of 5. Therefore it reaches to (20,25) to the left and (30,25) to the right of the center of the matrix. I know the formula for distance calculation is pdist([dpx,dpy;centerx,centery]). But how do I set this up so that matlab will identify all the points within the radius of 5. Im trying to multiple all these points (only the points within the radius of the turbine) by their distance from the center of the matrix. I imagine a for loop is required but I have no idea how to apply it.
Create a coordinate grid:
[x, y] = meshgrid(1 : 50);
Compute the distance of each grid point from (25, 25):
d = sqrt((x - 25) .^ 2 + (y - 25) .^ 2);
Generate a logical array that contains 1 (true) for every grid place within the turbine area:
turb = (d <= 5);
You can plot the result:
imagesc(turb)
axis equal tight
Or use turb for selecting values from a measurement matrix m
m(turb)
using logical indexing.
Note that indices (25, 25) do not denote the center of a 50 x 50 grid, but rather (25.5, 25.5).
Using logical indexing, you can find the relevant indexes in the matrix and select only them:
[x,y] = meshgrid(1:50);
centered_valued = ((x-25).^2+(y-25).^2 <= 5^2);
requested_matrix = originalMatrix(centered_values);
The meshgrid function computes two matrices: the first one contains the x indexes in every row, the second one contains the y indexes of every column.
You then use boolean computation to find the indexes which are within the radius from the center (located in (25,25).
This logical array then can be used as an "index" for the original matrix. The result will be a smaller matrix (though you might be forced to use the (:) operator, as the result is not necessarily a rectangular matrix).
If you have the image processing toolbox, you can also use the bwdist command to do the distance calculation for you.
Create a mask with the center point selected:
bw = zeros(50,50); bw(25,25) = 1;
Calculate the distance to each point from the center (note bwdist also allows for a variety of distance calculations, see doc bwdist for details)
distance = bwdist(bw);
Create a mask of the turbine pixels:
turbine = (distance <= 5);
You asked about multiplying pixels in the turbine by their distance from the center. If the original data is stored in the 50x50 matrix orig, then you can do:
orig(turbine) = orig(turbine) .* distance(turbine);

extracting matrix values from another matrix

I have a problem like that;
points (size = 65,2) is a variable that has pixel coordinates of an image. In the first column, there are x coordinates, and in the second y coordinates and I want to take the magnitude values of a matrix (size = 256,256,6) from those pixel coordinates of only one channel eg. 3 (three).
I couldn't succeed that.
intensities = images(points(:,2), points(:,1), 3);
makes a matrix 65x65.
Thanks
Jimenez
You can convert your x,y indices to linear indices to get values you want from your image:
% some sample data
list = round(256*rand(65,2));
im = rand(256,256);
% calculate linear indices
ind = sub2ind([256,256],list(:,1),list(:,2));
intensities = im(ind);
This results in an intensities matrix that is 65x1 where each element corresponds to the x,y pair from your list.

Finding the belonging value of given point on a grid of 3D histogram?

I use 2D dataset like below,
37.0235000000000 18.4548000000000
28.4454000000000 15.7814000000000
34.6958000000000 20.9239000000000
26.0374000000000 17.1070000000000
27.1619000000000 17.6757000000000
28.4101000000000 15.9183000000000
33.7340000000000 17.1615000000000
34.7948000000000 18.2695000000000
34.5622000000000 19.3793000000000
36.2884000000000 18.4551000000000
26.1695000000000 16.8195000000000
26.2090000000000 14.2081000000000
26.0264000000000 21.8923000000000
35.8194000000000 18.4811000000000
to create a 3D histogram.
How can I find the histogram value of a point on a grid? For example, if [34.7948000000000 18.2695000000000] point is given, I would like to find the corresponding value of a histogram for a given point on the grid.
I used this code
point = feat_vec(i,:); // take the point given by the data set
X = centers{1}(1,:); // take center of the bins at one dimension
Y = centers{2}(1,:); // take center of the bins at other dim.
distanceX = abs(X-point(1)); // find distance to all bin centers at one dimension
distanceY = abs(Y-point(2)); // find distance to center points of other dimension
[~,indexX] = min(distanceX); // find the index of minimum distant center point
[~,indexY] = min(distanceY); // find the index of minimum distant center point for other dimension
You could use interp2 to accomplish that!
If X (1-D Vector, length N) and Y (1-D vector, length M) determine discrete coordinate on the axes where your histogram has defined values Z (matrix, size M x N). Getting value for one particular point with coordinates (XI, YI) could be done with:
% generate grid
[XM, YM] = meshgrid(X, Y);
% interpolate desired value
ZI = interp2(XM, YM, Z, XI, YI, 'spline')
In general, this kind of problem is interpolation problem. If you would want to get values for multiple points, you would have to generate grid for them in similar fashion done in code above. You could also use another interpolating method, for example linear (refer to linked documentation!)
I think you mean this:
[N,C] = hist3(X,...) returns the positions of the bin centers in a
1-by-2 cell array of numeric vectors, and does not plot the histogram.
That being said, if you have a 2D point x=[x1, x2], you are only to look up the closest points in C, and take the corresponding value in N.
In Matlab code:
[N, C] = hist3(data); % with your data format...
[~,indX] = min(abs(C{1}-x(1)));
[~,indY] = min(abs(C{2}-x(2)));
result = N(indX,indY);
done. (You can make it into your own function say result = hist_val(data, x).)
EDIT:
I just saw, that my answer in essence is just a more detailed version of #Erogol's answer.

How to assign values to particular point in 3D rectangle in matlab

I want to animate the varying temperature gradient in 3D rectangle. I have temperature values at specified points in a real container. I am not been able to figure out how to pass the temperature values as specified point in 3D container in Matlab.Lets say I have 10 points on one side of rectangle and same as on other remaining five sides.
any suggestions
Let's assume that your rectangular container is oriented in space with one vertex at (0,0,0) and sides along x, y and z axis. And you have set of points each with 3-point coordinate (x,y,z). In MATLAB it's probably represented by 3 vectors X, Y and Z. You also have a vector of temperature values (say T) for each points.
Then you can use SCATTER3 function to plot the points:
scatter3(X,Y,Z,[],T,'.')
You can change the size of points substituting the empty parameter with a value.
If you have point only on the faces of the container, it means one of the coordinate is either 0 or the size of corresponding side.
the colors are controlled by current color map. You can change it with COLORMAP function. For temperature the good one is 'hot' or 'cool'. Show the color scale with COLORBAR.
Here is an example with random data:
%# random coordinates
X = rand(60,1,1);
Y = rand(60,1,1);
Z = rand(60,1,1);
%# put the points into faces
X(1:10) = 0;
X(10:20) = 1;
Y(20:30) = 0;
Y(30:40) = 1;
Z(40:50) = 0;
Z(50:60) = 1;
%# temperature vector
T = rand(60,1,1) * 100;
%# plot
scatter3(X,Y,Z,[],T,'.')
grid off
box on
colormap hot
colorbar
Temp=zeros(10,10,10);
Temp(5,2,4)=25;