I have 4 2D points in screen-space, and I need to reverse-project them back into 3D space. I know that each of the 4 points is a corner of a 3D-rotated rigid rectangle, and I know the size of the rectangle. How can I get 3D coordinates from this?
I am not using any particular API, and I do not have an existing projection matrix. I'm just looking for basic math to do this. Of course there isn't enough data to convert a single 2D point to 3D with no other reference, but I imagine that if you have 4 points, you know that they're all at right-angles to each other on the same plane, and you know the distance between them, you should be able to figure it out from there. Unfortunately I can't quite work out how though.
This might fall under the umbrella of photogrammetry, but google searches for that haven't led me to any helpful information.
If you know the shape is a rectangle in a plane, you can greatly further constrain the problem. You certainly cannot figure out "which" plane, so you can choose that it is lying on the plane where z=0 and one of the corners is at x=y=0, and the edges are parallel to the x/y axis.
The points in 3d are therefore {0,0,0},{w,0,0},{w,h,0},and {0,h,0}. I'm pretty certain the absolute size will not be found, so only the ratio w/h is releavant, so this is one unknown.
Relative to this plane the camera must be at some point cx,cy,cz in space, must be pointing in a direction nx,ny,nz (a vector of length one so one of these is redundant), and have a focal_length/image_width factor of w. These numbers turn into a 3x3 projection matrix.
That gives a total of 7 unknowns: w/h, cx, cy, cz, nx, ny, and w.
You have a total of 8 knowns: the 4 x+y pairs.
So this can be solved.
Next step is to use Matlab or Mathmatica.
This is the Classic problem for marker based Augmented Reality.
You have a square marker (2D Barcode), and you want to find its Pose (translation & rotation in relation to the camera), after finding the four edges of the marker. Overview-Picture
I'm not aware of the latest contributions to the field, but at least up to a point (2009) RPP was supposed to outperform POSIT that is mentioned above (and is indeed a classic approach for this) Please see the links, they also provide source.
http://www.emt.tugraz.at/~vmg/schweighofer
http://www.emt.tugraz.at/publications/EMT_TR/TR-EMT-2005-01.pdf
http://www.emt.tugraz.at/system/files/rpp_MATLAB_ref_implementation.tar.gz
(PS - I know it's a bit old topic, but anyway, the post might be helpful to somebody)
http://library.wolfram.com/infocenter/Articles/2794/
http://campar.in.tum.de/Students/SepPoseEstimation
http://opencvlibrary.sourceforge.net/Posit will sorta work, but it can diverge or loop.
I'll get my linear Algebra book out when I get home if nobody answered. But @ D G, not all matrices are invertible. Singular matrices aren't invertible (when determinant = 0). This will actually happen all the time, since a projection matrix must have eigenvalues of 0 and 1, and be square (since it is idempotent, so p^2 = p).
An easy example is, [[0 1][0 1]] since the determinant = 0, and that is a projection on the line x = y!
Thanks to @Vegard for an excellent answer. I cleaned up the code a little bit:
The approximate call with .1 did not work for me, so I took it out. I ran it for a while too, and last I checked it was at
with an error around 0.02.
For my OpenGL engine, the following snip will convert mouse/screen coordinates into 3D world coordinates. Read the commments for an actual description of what is going on.
void YCamera :: CalculateWorldCoordinates(float x, float y, YVector3 *vec) { // START GLint viewport[4]; GLdouble mvmatrix[16], projmatrix[16];
}