extracting matrix values from another matrix - matlab

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.

Related

MATLAB 3D matrix, max in different directions + rotation using MIP

I have a 3D image called img, let's say it is a 291x287x801 int16 array. I am using the MIP (Maximum intensity projection) to find the image with the maximum intensity in different directions. I know that I could use max to get the MIP:
MIPimg=max(img,[],3);
imagesc(MIPimg);
However, this is not giving me the right direction. I think it is along the z-direction, but what should I do if I want to find the MIP along the y or x direction?
I did try to change that 3 which indicates dimension to 1 or 2, but MATLAB tells me
Error using image
Color data must be an m-by-n-by-3 or m-by-n matrix.
when calling imagesc(MIPimg).
I also tried MIPimg=max(img,[ ],[2 3]); but that didn't help.
Your problem is that imagesc expects either a 2D array as input, or a 3D array where the 3rd dimension has exactly 3 values (this is the way MATLAB represents an RGB image). When you do max(img,[],1), you get an 1x287x801 array back, which has 801 elements along the 3rd dimension, not 3 as MATLAB expects.
What you need to do for display is to convert this 1x287x801 array into an 287x801 array. The function squeeze does this (it removes all dimensions with size 1):
MIPimg = squeeze(max(img,[],1));
I cannot reproduce your problem:
% create random 3D-unit8-matrix (to mimic an image)
img = uint8(randi(255,10,12,3)); % 10x12x3 matrix
% maximum over all rows (direction 1) of each of the 3 10x12 matrices => returns 3 1x12 arrays
[val,idx] = max(img,[],1); % default direction
% maximum over all columns (direction 2) of each of the 3 10x12 matrices => returns 3 10x1 vectors
[val,idx] = max(img,[],2);
% maximum over all slices (direction 3) of each of the 10x12 1x3 "depth" arrays => returns a 10x12 matrix
[val,idx] = max(img,[],3);
overall maximum
max(max(max(img))) % no useful information about the position
position of maximum:
[val_slc,idx_slc] = max(img,[],3); % I can better think in 2D
[val_row,idx_row] = max(val_slc);
[val_col,idx_col] = max(val_row);
idx_max = [idx_row(idx_col),idx_col,idx_slc(idx_row(idx_col),idx_col)];
check
assert( max(max(max(img))) == img(idx_max(1),idx_max(2),idx_max(3)) )

Finding points in array that is in the specified rectangle( matlab)

I have a matrix that is consists of some points of image.look at below
Cout=
[215,59;165,126;215,72;236,65;258,60;296,71;296,84;246,77;240,120;228,120;225,74;176,58;178,72];
Now I want to find points in rectangle below [x,y,width,height]
rec=[105,210,31,31]
How should I code it in Matlab?
Thanks.
Use inpolygon.[https://www.mathworks.com/help/matlab/ref/inpolygon.html]
HOW IT WORKS:
in = inpolygon(xq,yq,xv,yv) returns in indicating if the query points specified by xq and yq are inside or on the edge of the polygon area defined by xv and yv.
xq: x-coordinates of query points, specified as a scalar, vector, matrix, or multidimensional array(The size of xq must match the size of yq).
yq: y-coordinates of query points, specified as a scalar, vector, matrix, or multidimensional array.
xv: x-coordinates of polygon vertices, specified as a vector(The size of xv must match the size of yv).
yv: y-coordinates of polygon vertices, specified as a vector.
in: Indicator for the points inside or on the edge of the polygon area, returned as a logical array. in is the same size as xq and yq.
% points of image you're searching
% (x,y) are not the coordinates of matrices in MATLAB! And images are
% matrices. The coordinates of matrices are (row, column) which is NOT (x,y) - it's (y,x).
yq=Cout(:,1)
xq=Cout(:,2)
xv=[rec(1);rec(1);rec(1)+rec(3);rec(1)+rec(3);rec(1)];
yv=[rec(2);rec(2)+rec(4);rec(2)+rec(4);rec(2);rec(2)];
in = inpolygon(xq,yq,xv,yv)
I find 2 points by this way.
here is what you need (I think):
Cout= [235,65;296,71;296,84;240,120;229,119;224,74;165,126];
Rec=[105,210,31,31];
% set the range of the rectangle in x and y
xr=[Rec(2) (Rec(2)+Rec(4))];
yr=[Rec(1) (Rec(1)+Rec(3))];
% draw the rectangle for ref
rectangle('Position',Rec); hold on
% the next line is what you asked for, checking if points fall in the
% rectangle I chose here limits with < and >, but you may want <= and >= ...
id = Cout(:,1)<xr(end) & Cout(:,1)>xr(1) & Cout(:,2)<yr(end) & Cout(:,2)>yr(1);
% let's check:
plot(Cout(:,2),Cout(:,1),'x',Cout(id,2),Cout(id,1),'ro')

Centroid calculation for a connected component in 3D volume using 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.

Adding Specific Coordinates of a Matrix in Matlab

I am trying to find the sum of certain coordinates in a matrix.
I have a N x M matrix. I have a vector which contains 2xM values. Every pair of values in the vector is a coordinate in the matrix. Hence their are M number of coordinates. I want to find the sum of all of the coordinates without using a for loop.
Is there a matrix operation I can use to get this?
Thanks
As I understand it the vector contains the (row,column) coordinates to the matrix elements. You can just transform them into matrix element number indices. This example shows how to do it. I'm assuming that your coordinate vector looks like this:
[n-coordinate1 m-coordinate1 n-coordinate2 m-coordinate2 ...]
n = 5; % number of rows
m = 5; % number of columns
matrix = round(10*rand(n,m)); % An n by m example matrix
% A vector with 2*m elements. Element 1 is the n coordinate,
% Element 2 the m coordinate, and so on. Indexes into the matrix:
vector = ceil(rand(1,2*m)*5);
% turn the (n,m) coordinates into the element number index:
matrixIndices = vector(1:2:end) + (vector(2:2:end)-1)*n);
sumOfMatrixElements = sum(matrix(matrixIndices)); % sums the values of the indexed matrix elements
If you want to find the centroid of your 2xM array coords, then you can simply write
centroid = mean(coords,2)
If you want to find the weighted centroid, where each coordinate pair is weighted by the corresponding entry in the MxN array A, you can use sub2ind like this:
idx = sub2ind(size(A),coords(1,:)',coords(2,:)');
weights = A(idx);
weightedCentroid = sum( bsxfun( #times, coords', weights), 1 ) / sum(weights);
If all you want is the sum of all the entries to which the coordinates point, you can do the above and simply sum the weights:
idx = sub2ind(size(A),coords(1,:)',coords(2,:)');
weights = A(idx);
sumOfValues = sum(weights);

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.