Here's Giorgio de Chirico's painting, Ariadne:
The Surrealist artist deliberately broke the rules of geometric perspective, giving the work his characteristic sense of mystery and unease.
What would the work look like if the perspective were instead consistent? Specifically, here are potential perspective lines (in red):
Here are the coordinates of the lines:
Show[ariadne,
Graphics[{Red, Thickness[0.01],
Line[{{280, 410}, {350, 450}}],
Line[{{530, 450}, {310, 400}}],
Line[{{280, 300}, {600, 20}}],
Line[{{300, 1}, {140, 280}}],
Line[{{130, 1}, {60, 250}}],
Line[{{250, 1}, {140, 250}}]
}]]
What I'm seeking is a global distortion of the painting such that the red perspective lines (extended) remain straight yet meet at a single vanishing point. (The ideal is that the user can specify the vanishing point's two-dimensional location, such as somewhere between the train and the white tower.)
While GeometricTransformation
s (such as a homography) can distort a single image patch, I've found it rather tricky to automatically distort the entire image to ensure a single vanishing point because the distortion is different in different locations.
I suspect the best approach is to split the image into wedges, between successive (red) perspective lines, then within each wedge transform the image to force the straight boundaries (defined by the perspective lines) to meet at the specified vanishing point. Thus the transformation will be different within each such wedge, yet the perspective lines will remain straight (as required).
(It would be very cool to create a Manipulate
which allowed the user to drag the central vanishing point around the plane, but this is not part of this question/request.)
Any suggestions?
Here's one approach that might work. Create consistent perspective lines on the target painting, all meeting at a single vanishing point. (Doing this by hand would be acceptable.) Then create a list of source points (on the original painting) with the corresponding points on the target painting, of the form $(x_i, y_i) \to (x_i^\prime , y_i^\prime )$. So you could make 10 points on each line with 10 points on each target line.
Then, learn a two-dimensional interpolation function, $f(x,y) = (x^\prime, y^\prime)$. Implement this with ImageTransformation
. Finally, apply this interpolation function to all points in the original painting.
It would be important to find the simplest function $f$ that maps the data points (or increase the total number of such points selected from lines, or create more perspective lines) in order to ensure that the mapping is one-to-one (i.e., the target images doesn't "fold over" upon itself).
Maybe this will work....