# Can Mathematica be used to make anamorphic distortions like these?

We have all see these sidewalk and street images that appear to be 3D based on the viewers perspective, but then wildly distort when viewed from a different perspective.  Seems to me anamorphic distortion like this would be something Mathematica could do quite easily, but see only manual methods being used when searching the webs for instructions. Given that simple triangulated perspective would work, the variables would be viewing height, viewing distance and size of the actual chalk drawing. That would produce the triangle needed for distorting the perspective.

So for those variables the average US male is 5'9.5" and the viewing distance of 10 feet and the size of the projected image would be 20 feet tall. Using the above normal perspective image image, how can Mathematica be used to create a distorted version that would view properly using the variables of viewer height, distance and viewing angle?

Here is an example done in Photoshop of the Captain America image that has been perspective distorted to appear correct when placed on the ground, by a person who's 5'10" and is 10 feet away • related: QR Code in shopping cart handle
– Kuba
Feb 15, 2017 at 18:14
• @Kuba Basically, it is a duplicate as the method behind it is exactly the same. Feb 17, 2017 at 21:10

h = 6.0;  (* eye height *)
h0 = 4.0;  (* apparent image height *)
d = 10.0;  (* apparent image distance *)
a = d h0/(h - h0);  (* actual length of painting *)


The geometry is like this: Now do the transformation.

myimage = ImageResize[Import@"https://i.stack.imgur.com/k78e8.jpg", Scaled[1/5]];

f[{x_, y_}] := h/(h - y) {x, d}

w0 = h0 Divide @@ ImageDimensions[myimage]
(* 3.20667 *)

i = ImageForwardTransformation[myimage, f,
DataRange -> {{-w0/2, w0/2}, {0, h0}},
PlotRange -> All, Background -> White];

b = a Divide @@ ImageDimensions[i]
(* 4.81791 *)


The resulting transformed image i: Using Mathematica's 3D graphics we can paint the transformed image on the ground and view from the appropriate point:

Graphics3D[{Table[{Orange,
Cylinder[{{-b/2, y, 0}, {-b/2, y, 1}}, 0.1],
Cylinder[{{b/2, y, 0}, {b/2, y, 1}}, 0.1]}, {y, d, a + d, 2}],
Texture[i],
Polygon[{{-b/2, d, 0}, {-b/2, d + a, 0}, {b/2, d + a, 0}, {b/2, d, 0}},
VertexTextureCoordinates -> {{0, 0}, {0, 1}, {1, 1}, {1, 0}}]},
ViewVector -> {{0, 0, h}, {0, (d + a)/2, 0}},
ViewAngle -> 0.5, Lighting -> "Neutral", Boxed -> False] • Very good answer! Missing the viewing angle variable, but otherwise correct! Feb 18, 2017 at 12:15
• @RHall I'm not sure what you mean by viewing angle Feb 18, 2017 at 12:20
• so for example if the surface the new image is placed on it angled differently than say ground level. Like a ramp which angles up and away, or a wall that angles away from the viewer. Feb 18, 2017 at 12:24
• @RHall in that case I think the same approach should work but you'll need to adjust the transformation function f. Feb 18, 2017 at 13:57
• This just in...ImageForwardTransformation is now broken, confirmed by MMA Support Sept 2017 Oct 13, 2017 at 15:41

Yes. Simply use: ImagePerspectiveTransformation[]

myimage = Import@"https://i.stack.imgur.com/k78e8.jpg";


For example, define myimage to be your image. Then:

ImagePerspectiveTransformation[myimage, TransformationFunction[( \!$$\* TagBox[GridBox[{ {"0", "1", "0.5"}, {"2", "0.5", "0.1"}, {"2", "0", "1.5"} }, AutoDelete->False, GridBoxDividers->{ "Columns" -> {{False}}, "ColumnsIndexed" -> {-2 -> True}, "Rows" -> {{False}}, "RowsIndexed" -> {-2 -> True}, "Items" -> {}, "ItemsIndexed" -> {}}, GridBoxItemSize->{ "Columns" -> {{Automatic}}, "ColumnsIndexed" -> {}, "Rows" -> {{Automatic}}, "RowsIndexed" -> {}, "Items" -> {}, "ItemsIndexed" -> {}}], #& ]$$ )]] The way to set the geometry for a given viewing position is illustrated here (see Seeing the light: Optics in nature, photography, color, vision and holography by Falk, Brill and Stork): the height of the viewer's eye is given by the top of the right vertical line, a C. Draw a straight line from that point through the right of the base of the transformed image and then continue to the bottom left and use a straightedge accordingly. When viewed from that upper right point, the picture will appear undistorted. • @corey: I recommend you wait more than two (yes, literally two) minutes to judge an answer, as answerers typically take some time to fill out a full answer. Feb 15, 2017 at 18:39
• how would this solution allow for the variables of observer height, viewing distance and angle as mentioned above to provide the viewer with an accurate image from their perspective? Feb 15, 2017 at 18:53