Good day to all! My task is as follows: there is an array of points in space that form an ellipse, and this array must be designed on a 2D image (as if we were getting an image from a camera). My problem is that in some cases, instead of an ellipse, I can get a hyperbola, which is not good. How to avoid such cases? I do the mapping in the matlab as follows:
function [u,v] = point2camProjection(point,f,Oc)
K = [f,0,Oc(1);0,f,Oc(2);0,0,1];
UVW = K*point;
u=UVW(1)/UVW(3);
v=UVW(2)/UVW(3);
end
point is the coordinates of the 3D point, f is the focal length of the camera, and Oc is the optical center of the camera.
Related
I have made 3D analysis code and I want to split or crop 3D mesh into 2 parts with 2D plane, what i expected: the final result I need is to find out what are the nodes on the left side and the right side, what you see on the image below is the nodes of the 3D object (bumpy), Do you know what method or library I need to use to solve this problem?
my problem
Here is my data structure from the 2D plane:
Column 1: Face
Column 2: X coordinate
Column 3: Y coordinate
column 4: Z coordinate
Column 5: Finite Element Value
data structure
.
The data structure from the 3D mesh is containing the same data as the table above, Thanks so much!
We can know the plane XYZ Coordinates, so I tried to find by using <= to find the axis value is larger or smaller than the plane coordinates:
find x,y,z 3D model coordinate is smaller than x,y,z cut plane coordinate
[r] = find((Name_OT(:,1)>=x) & (Name_OT(:,2)>=y) & Name_OT(:,3)>=z);
the blue line is the plane, and the coloured one is the result from my code, the ideal result is the coloured nodes full, but what happened here the colour node has a big hole or gap
not good result
You need to first decide whether you want to segment your data by a (linear) plane or not. If you prefer to keep a curved surface, please follow my earlier comment and edit your question.
To get a plane fit to the data for your cut, you can use fit.
Base on the plane, you can get a normal vector of the plane. That is reading coefficients of fit results and is in the documentation. Using that normal vector, you can rotate all your data so that the plane is normal to z axis. The rotation is matrix multiplication. From there, you can use logical indexing to segment your data set.
You can ofc also get the normal component of the data points relative to the plane cut and decide on a direction that way. You still need fit. From that point, it's basic matrix manipulation. An nx1 vector can multiply a 1xn vector in Matlab. So projectors can also be constructed from basic matrix manipulation. At a glance, this method is computationally inefficient.
I captured a depth image of a human body in the room and I collected and saved Skeletal data related to that depth image (the joints of wrists, elbows, ...).
Considering the joints' coordinates are in the camera space and depth image is in depth space, I was able to show the location of the right hand wrist joint on depth image using this code:
depthJointIndices = metadata.DepthJointIndices(:, :, trackedBodies);
plot(depthJointIndices(11,1), depthJointIndices(11,2), '*');
Now I want to know which pixel EXACTLY contains the right hand wrist joint, how can I do this properly?
I thought that I can get the coordinate of x,y of that joint using the code I used to show the right hand wrist joint.
As follows:
depthJointIndices = metadata.DepthJointIndices(:, :, trackedBodies);
x=depthJointIndices(11, 1)
y=depthJointIndices(11, 2)
But x,y are calculated as follows:
x = 303.5220
y = 185.6131
As you can see x,y are Floating-point numbers, but coordinates of pixels can't be Floating-point numbers.
So can anyone help me with this problem? how can I get coordinate of a pixel that is containing right hand wrist joint, in depth image, using kinect?
You can use the following 2 equations to derive the coordinates.
Here,
(U,V) and Z denote screen coordinates and depth value, respectively, Cx and Cy denote the center of a depth map, and fx and fy are the focal lengths of the camera. For Kinect-V1 cameras, fx = fy = 580
You can refer the paper Action Recognition From Depth Maps Using Deep Convolutional Neural Networks by P. Wang et.al for more information.
Trying to reconstruct 3D-coordinates of point on plane from 2D-Pixel-Coordinates in a Camera Picture, using a extrinsic and intrinsic camera parameters from "Camera Calibration Toolbox for Matlab".
intrinsic parameters:
Focal Length: fc = [ 1017.21523 1012.54901 ]
Principal point: cc = [ 319.50000 239.50000 ]
extrinsic parameters:
Translation vector: Tc_ext = [ 4.409693 -74.116018 393.057934 ]
Rotation matrix: Rc_ext = [ -0.083632 0.991715 -0.097501
0.832136 0.015674 -0.554350
-0.548230 -0.127495 -0.826553 ]
Can anybody help how to get 3d-coordinates of point on plane from 2d from camera image?
There are 4 cases to consider, in order of increasing complexity. The basic goal is to locate in space the plane of interest. After you have it, you can just intersect it with the ray that back-projects your pixel and thus obtain the solution.
The plane of interest contains the checkerboard target AND the image is one of those you used to calibrate the camera. Then the extrinsic parameters [R | T] for that image returned by the calibration routine contain the answer, since the target is the XY plane of the returned world-to-camera coordinate transform at that image, and the world origin is one of the corners (you can see which corner it is by projecting point (0,0,0) into image coordinates. The XY plane (in camera coordinates) is the plane spanned by the first two columns of the rotation matrix R, and its origin is at point T.
The plane of interest contains the checkerboard target, but its image is NOT one of those used to calibrate. You could just add it to the set, re-calibrate and goto 1., but a faster alternative is to (a) extract the corners as you do for calibration, (b) compute the homography H from their image positions to their "true" position on the physical target at Z=0; (c) decompose H into K * [R | T] using the known K from the calibration (you use an algorithm called "RQ decomposition" for this purpose, look it up). Then goto 1.
The calibration target is not in the image, but you can identify in the image at least 4 points on that plane, such that no 3 of them are collinear and they are at known positions with respect to each other. For example, you see a rectangle of known sides in the image. Then, just like in point 2. you can compute the homography between those physical points and their images, and extract the [R|T] transform knowing the camera matrix. Then goto 1.
None of the above: sorry, you are stuck.
I have given 3d points of a scene or a subset of these points comprising one object of the scene. I would like to create a depth image from these points, that is the pixel value in the image encodes the distance of the corresponding 3d point to the camera.
I have found the following similar question
http://www.mathworks.in/matlabcentral/newsreader/view_thread/319097
however the answers there do not help me, since I want to use MATLAB. To get the image values is not difficult (e.g. simply compute the distance of each 3d point to the camera's origin), however I do not know how to figure out the corresponding locations in the 2d image.
I could only imagine that you project all 3d points on a plane and bin their positions on the plane in discrete, well, rectangles on the plane. Then you could average the depth value for each bin.
I could however imagine that the result of such a procedure would be a very pixelated image, not being very smooth.
How would you go about this problem?
Assuming you've corrected for camera tilt (a simple matrix multiplication if you know the angle), you can probably just follow this example
X = data(:,1);
Y = data(:,1);
Z = data(:,1);
%// This bit requires you to make some choices like the start X and Z, end X and Z and resolution (X and Z) of your desired depth map
[Xi, Zi] = meshgrid(X_start:X_res:X_end, Z_start:Z_res:Z_end);
depth_map = griddata(X,Z,Y,Xi,Zi)
I have a 3D matrix of data in matlab, but I want to extract an arbitrarily rotated slice of data from that matrix and store it as a 2D matrix, which I can access. Similar to how the slice() function displays data sliced at any angle, except I would also like to be able to view and modify the data as if it were an array.
I have the coordinates of the pivot-point of the plane as well as the angles of rotation (in x, y and z axis), I have also calculated the equation of the plane in the form:
Ax + By + Cz = D
and can extract a 3D matrix containing only the data that fall on that plane, but I don't know how to then convert that into a simple 2D array.
Another way of doing it would be to somehow rotate the source matrix in the opposite direction of the angle of the plane, so as to line up the plane of data with the XY axis, and simply extract that portion of the matrix, but I do not know if rotating a matrix like that is possible.
I hope this hasn't been answered elsewhere, I've been googling it all day, but none of the problems seem to exactly match mine.
Thanks
You can take a look at the code here. I think the function is similar to what you are trying to solve.
The function extracts an arbitrary plane from a volume given the size of the plane, the center point of the plane, and the plane normal, i.e. [A,B,C]. It also outputs the volumetric index and coordinate of each pixel on the plane.
Aha! May have just solved it myself.
To produce the plane equation I rotate a normal vector of (0,0,1) using rotation matrices and then find D. If I also rotate the following vectors:
(1,0,0) //step in the x direction of our 2D array
and
(0,1,0) //step in the y direction of our 2D array
I'll have the gradients that denote how much my coordinates in x,y,z have to change before I step to the next column in my array, or to the next row.
I'll mock this up ASAP and mark it as the answer if it works
EDIT: Ok slight alteration, when I'm rotating my vectors I should also rotate the point in 3D space that represents the xyz coordinates of x=0,y=0,z=0 (although I'm rotating around the centre of the structure, so it's actually -sizex/2,-sizey/2,-sizez/2, where size is the size of the data, and then I simply add size/2 to each coordinate after the rotations to translate it back to where it should be).
Now that I have the gradient change in 3D as I increase the x coordinate of my 2D array and the gradient change as I increase the y coordinate, I can simply loop through all possible x and y coordinates (the resulting array will be 50x50 for a 50x50x50 array, I'm not sure what it will be for irregular sizes, which I'll need to work out eventually) in my 2D array and calculate the resulting 3D coordinates on my plane in the data. My rotated corner value serves as the starting point. Hooray!
Just got to work out a good test for this encompassing all angles and then I'll approve this as an answer