2d median filter of arbitrary x,y coordinates in matlab - matlab

I have a set of x,y coordinates and intensity (x,y,I). These x,y coordinates are not uniform and do not form an ordered 2d array. I'd like to 2D median filter the intensity based on the x,y coordinates . Unfortunately I cant simply use medfilt2 because they are not ordered or uniformly spaced.
What I tried:
make a map of the neighborhood of each (x,y) coordinate:
for i=1:numel(x)
neighbo{i}=find(sqrt( (x-x(i)).^2+(y-y(i)).^2)<150);
end
this is already a problem as the the vector x is 1e7 long, and it takes really a long time just to do that.
next I'd sort each neighbo{i} and pick the central value, I can just imagine it would take just as long.
Any advice on how to achieve that median filtering, or make the above more efficient ?

Related

MATLAB: converting 3d plane into 3d matrix pixel locations

I am trying to get a slice of an elongated object in a 3d matrix (227x297x187 binary) that is orthogonal to its orientation..i.e. output image would be a 2d cross-section.
I was thinking the best way to do this would be to find a vector giving the orientation at some point on the object (so for a cross-section at the 40th slice I get the location of centroids at the 30th and 50th slices and find the vector between them), then get a list of pixels corresponding to a plane orthogonal to that vector at the desired slice (along centroid of object at 40th slice), and then retrieve the values in the matrix corresponding to those locations. Assuming the code I have attached finds the plane, I can plot it with surf() but don't know how to translate that into pixel locations in the matrix to generate the values for the 2d cross-section.
startslice=30;
endslice=50;
startnums=bwconncomp(binMATRIX(:,:,startslice));
startnums=regionprops(startnums,'Centroid');
endnums=bwconncomp(binMATRIX(:,:,endslice));
endnums=regionprops(endnums2,'Centroid');
midnums3=bwconncomp(binMATRIX(:,:,(startslice+(endslice-startslice)/2)));
midnums3=regionprops(midnums,'Centroid');
startstuff=[startslice, startnums.Centroid];
endstuff=[endslice, endnums.Centroid];
midstuff=[(startslice+(endslice-startslice)/2), midnums.Centroid];
nullstuff=null(endstuff-startstuff);
A=nullstuff(:,1);
B=nullstuff(:,2);
[x,y]=meshgrid(A,B);
z=1-x-y;
surf(x+midstuff(1),y+midstuff(2),z+midstuff(3))

[Paraview]- Compare two Vtk mesh surface to calculate the deformation distance

I have a tof camera (pmd camboard nano), and my goal it's to between meshes calculate the distance from each other to calculate the deformation distance and the 3d position of specific points.
What is the best method to make that? I try with ruler, and euclidian distance in matlab with the point source, but i want the calcultion to be more precise.
Here's a solution, assuming both datasets have exactly the same number of points and you are comparing point coordinates for points at the same index:
Apply the Calculator filter on both the datasets separately with the expression coords. This will create new datasets with Result array in the PointData that corresponds to the point locations for each of the datasets.
Select the two calculator filters and then apply the Python Calculator filter with expression set to sqrt(sum((inputs[0].PointData["Result"] - inputs[1].PointData["Result"])**2)).
The resulting dataset will have a result array which is the euclidean distance between the two corresponding points.
To limit this calculation to specific points, you can use the Extract Selection or Threshold to extract smaller datasets with points of interest and then do the above.

Mapping coordinates list and Rectangles list by binning

I have a large MxN array of coordinates and I have a large set of rectangles in a structure Rect.Now i am calculating the density of each of the rectangles buy calculating the area/no of points inside it. In Matlab an inefficent way to handle this would be something like below
for ii=1:size(Rect,1)
ind = X>Rect(ii,1) & X<Rect(ii,3) & Y>Rect(ii,2) & Y<Rect(ii,4);
Num_of_coord(ii) = sum(ind);
end
I want to partition my data in 2D bins, say with N=10. How can i bin my Rect and XY coordinate data into each square ? The idea is i don't have to compare all XY coordinates with all Rectangles.
Thanks

Find closest point in matlab grid

G'day
I'm trying to program a smart way to find the closest grid points to the points along a contour.
The grid is a 2-dimensional grid, stored in x and y (which contain the x and y kilometre positions of the grid cells).
The contour is a line, made up of x and y locations, not necessarily regularly spaced.
This is shown below - the red dots are the grid, and the blue dots are the points on the contour. How do I find the indices of the red dot closest to each blue dot?
Edit - I should mention that the grid is a latitude/longitude grid, of an area fairly close to the south pole. So, the points (the red dots) are the position in metres from the south pole (using a polar stereographic representation). Since the grid is a geographic grid there is unequal grid spacing - with slightly different shaped cells (where the red dots define the vertices of the cells) due to the distortion at high latitudes.
The result is that I can't just find which row/column of the x and y matrix corresponds closest to the input point coordinates - unlike a regular grid from meshgrid, the values in the rows and columns vary...
Cheers
Dave
The usual method is to go:
for every blue point {
for every red point {
is this the closest so far
}
}
But a better way is to put the red data into a kd tree. This is a tree that splits the data along its mean, then splits the two data sets along their means etc until you have them separated into a tree structure.
This will change your searching effeciancy from O(n*m) to O(log(n)*m)
Here is a library:
http://www.mathworks.com.au/matlabcentral/fileexchange/4586-k-d-tree
This library will provide you the means to easily make a kd tree out of the data and to search for the closest point in it.
Alternatively you can use a quadtree, not as simple but the same idea. (you may have to write your own library for that)
Make sure the largest data set (in this case your red points) go into the tree as this will provide the greatest time reduction.
I think I've found a way to do it using the nearest flag of griddata.
I make a matrix that is the same size as the grid x and y matrices, but is filled with the linear indices of the corresponding matrix element. This is formed by reshaping a vector (which is 1:size(x,1)*size(x,2)) to the same dimensions as x.
I then use griddata and the nearest flag to find the linear index of the point closest to each point on my contour (blue dots). Then, simply converting back to subscript notation with ind2sub leaves me with a 2 row vectors describing the matrix subscripts for the points closest to each point on the blue-dotted contour.
This plot below shows the contour (blue dots), the grid (red dots) and the closest grid points (green dots).
This is the code snippet I used:
index_matrix1 = 1:size(x,1)*size(x,2);
index_matrix1 = reshape(index_matrix1,size(x));
lin_ind = griddata(x,y,index_matrix1,CX,CY,'nearest'); % where CX and CY are the coords of the contour
[sub_ind(1,:),sub_ind(2,:)] = ind2sub(size(x),lin_ind);
I suppose that in the stereographic representation, your points form a neat grid in r-theta coordinates. (I'm not too familiar with this, so correct me if I'm wrong. My suggestion may still apply).
For plotting you convert from the stereographic to latitude-longitude, which distorts the grid. However, for finding the nearest point, consider converting the latitude-longitude of the blue contour points into stereographic coordinates, where it is easy to determine the cell for each point using its r and theta values.
If you can index the cell in the stereographic representation, the index will be the same when you transform to another representation.
The main requirement is that under some transformation, the grid points are defined by two vectors, X and Y, so that for any x in X and y in Y, (x, y) is a grid point. Next transform both the grid and the contour points by that transformation. Then given an arbitrary point (x1, y1), we can find the appropriate grid cell by finding the closest x to x1 and the closest y to y1. Transform back to get the points in the desired coordinate system.
dsearchn: N-D nearest point search.
[k, d] = dsearchn(A,B) : returns the distances, d, to the closest points. d is a column vector of length p.
http://au.mathworks.com/help/matlab/ref/dsearchn.html?s_tid=gn_loc_drop

Matlab 3d plot of indexed data

I am trying to plot a 3d view of a very large CT dataset. My data is in a 3d matrix of 2000x2000x1000 dimension. The object is surrounded by air, which is set to NaN in my matrix.
I would like to be able to see the greyscale value of the surface of the object (no isosurface) but I cannot quite work out how to do that in Matlab. Can anyone help me please?
Given that I a dealing with a huge matrix and I am only interested in the surface of the object, does anyone know a good trick how to reduce the size of my dataset?
The function surf(X,Y,Z) allows you to plot 3d data, where (X,Y) gives the coordinates in the x-y-plane while Z gives the z-coordinate and the surface color.
By default the function does not plot anything for the NaN entries, so you should be good to go with the surf function.
To set the surf-function to use a grayscale plotting use:
surf(matrix3d);
colormap(gray);
This plots the matrix in a surface plot and sets the colormap to grayscale.
In addition, as I understand your data, you might be able to eliminate entire plane-segments in your matrix. If for instance the plane A(1,1:2000,1:1000) is NaN in all entries you could eliminate all those entries (thus the entire Y,Z-plane in entry X=1). This will however require some heavy for loops, which might be over the top. This depends on how many data matrices you have compared to how many different plot you want for each matrix.
I will try to give you some ideas. I assume lack of a direct 3D "surface detector".
Since you have a 3D matrix where XY-planes are CT scan slices and each slice is an image, I would try to find edges of each slice say with edge. This would require some preprocessing like first thresholding each slice image. Then I can either use scatter3 to display the edge data as a 3D point cloud or delaunay3 to display the edge data as a surface.
I hope this will help you achieve what you are asking for.
I managed to get it working:
function [X,Y,Z,C] = extract_surface(file_name,slice_number,voxel_size)
LT = imread(file_name);%..READ THE 2D MAP
BW = im2bw(LT,1);%..THRESHOLD TO BINARY
B = bwboundaries(BW,8,'noholes');%..FIND THE OUTLINE OF THE IMAGE
X = B{1}(:,1);%..EXTRACT X AND Y COORDINATES
Y = B{1}(:,2);
indices = sub2ind(size(LT),X,Y);%..FIND THE CORRESPONDING LINEAR INDICES
C = LT(indices);%..NOW READ THE VALUES AT THE OUTLINE POSITION
Z = ones(size(X))*slice_number;
I can then plot this with
figure
scatter3(X,Y,Z,2,C)
Now the only thing I could improve is to have all these points in the scatter plot connected with a surface. #upperBound you suggested delaunay3 for this purpose - I cannot quite figure out how to do this. Do you have a tip?