Here's how I arrived at this (admittedly, quite ugly) mapping
function: The "right" function to map points from cylinder coordinates to image coordinates in a pinhole camera model is the one MarcoB linked to in his comment. In a nutshell:
{Sin[u],Cos[u],v,1}
converts from cylinder coordinates u,v
to (homogeneous) 3d coordinates
- which you then multiply by the camera projection matrix
- and use
Most[#]/Last[#]&
to convert from homogeneous coordinates to 2d euclidean coordinates.
The projection matrix contains several degrees of freedom (for camera position, orientation, "zoom" and so on). If you know the values for these, you can use that formula to project from the cylinder to the image, or solve for $u$ and $v$ and project from image coordinates to cylinder coordinates.
In the "marmalade jars" answer, however, I don't know these degrees of freedom, and instead tried to estimate them using FindMinimum
, and that's where I ran into problems:
- estimating some values (especially zoom vs. camera distance) given just the label's outline is ill-conditioned.
- and the inverse mapping from image coordinates to cylinder coordinates contains inverse trigonometric functions, and
FindMinimum
kept aborting because the mapping returned complex numbers.
To work around these problems, I've come up with the mapping
function you posted, which is an ad hoc approximation for vertical cylinders with no perspective distortion. With the added bonus that it's free of trigonometric functions and always returns real values.