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
Related
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 ?
Suppose I have an image
and then I use the code below
I=imread("image.bmp");
imshow(I); hold on; [B,L,N] = bwboundaries(I);
for k=1:length(B),
boundary = B{k};
plot(boundary(:,2), boundary(:,1),'.r')
end
The boundaries then look like
However, I don't just want the x,y coordinates of each pixel ON the boundaries. I also want the x,y coordinates of each pixel INSIDE the boundaries also
Is there a way to do this in Matlab?
EDIT: I want to store the row/column numbers for each object in separate matrices. So matrix A1 should store the row/column numbers for the white pixels in the big object, matrix A2 should store the row/column numbers for the white pixels in the circular object
I have a 3D data matrix which contains information about a scene (which voxels are free / occupied and belong to which class).
So far to plot the data I have to plot 2D slices using imagesc.
I'd like to plot the data as a pointcloud using Matlabs pcshow which should only display occupied voxels and the display the rest as empty space.
How can I convert my 3D matrix into a pointcloud object?
For some NxMxK matrix A where A == 255 indicates free voxels:
% make coordinate grid the size of A
[X,Y,Z] = meshgrid(1:size(A,1),1:size(A,2),1:size(A,3));
% move to xyz format
xyz=[X(:) Y(:) Z(:)];
% show points which are not free and where group values are used as color (scaled by to current colormap)
pcshow(xyz(A~=255,:),A(A~=255))
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
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?