I know that there are many posts about image treatment, but I still have trouble with this little challegene.
Baisically I want to remove the perspective distorsion form this image:
(source: http://www.canvas-of-light.com/2015/03/how-to-correct-perspective-distortion-in-lightroom-5/)
How I started: An image can be transformed in 2D (planar) using various transformation rules:
Source: https://www.microsoft.com/en-us/research/wp-content/uploads/2004/10/tr-2004-92.pdf
Those transformation can all be described by transformation matrices which map the untransformed image to the transformed one. The most general case (for planar) is the projective transformation.
The projective matrix:
ProjectMat2D[h00_, h01_, h02_, h10_, h11_, h12_, h20_, h21_,
h22_] := {{h00, h01, h02}, {h10, h11, h12}, {h20, h21, h22}};
ProjectMat2D[h00, h01, h02, h10, h11, h12, h20, h21,
h22] // MatrixForm
The projective matrix has 3x3 components, since it works with homogeneous coordinates. Homogenous coordinates are basically the normale coordinates with an added row of 1. {{x},{y},{1}} ... for more information: https://en.wikipedia.org/wiki/Homogeneous_coordinates
Finding the matrix coeffiecnts:
Now the task is to find the coefficient of the transformation matrix.
Let's first calculate the transformed xy-Vector in homognenous coordinates.
xyTransHomoge =
ProjectMat2D[h00, h01, h02, h10, h11, h12, h20, h21,
h22].{{x}, {y}, {1}}; xyTransHomoge // MatrixForm
To retreive the homogenous coordinates as output, the last row needs to be 1. Therefore we devide the vector by the value of the last entry (to make it 1)
Last[xyTransHomoge]
{h22 + h20 x + h21 y}
1/(h22 + h20 x + h21 y)*xyTransHomoge // MatrixForm
We drop the {1} entry and receive the projection formulas which map the transformed to the untransformed coordinates:
$x'=\frac{h00*x+h01*y+h02}{h20*x+h21*y+h22}$
$y'=\frac{h10*x+h11*y+h12}{h20*x+h21*y+h22}$
I find four points in the transformed image and the corresponding points in the untransfromed image (by assumption). Basically I say that the four points on the transformed image should be a rectangle on the untransformed image. -> same x Position for two points on a vertical line
We get set of 8 equations, which we can solve to find the matrix coeffiecnts.
We set h00=1, since the matrix needs only to be determined up to a insignificant multiplicative factor.
Okay, enough theory... let's do it:
Find two points witth should have the same x-coordinates:
x11 = 634.0260655160307; y11 = 672.1241170908934; x12 = 608.4425576092435; y12 = 523.0723753730896; Show[notreDame, Graphics[{Point[{x11, y11}, VertexColors -> Green], Point[{x12, y12}, VertexColors -> Green]}]]
Find two other points witth should have the same x-coordinates:
x21 = 926.9209508015505; y21 = 611.3228302929783; x22 = 938.2421227197373; y22 = 516.5080154781632; Show[notreDame, Graphics[{Point[{x21, y21}, VertexColors -> Green], Point[{x22, y22}, VertexColors -> Green]}]]
To find the corresponding homogenious coordinates (in undeformed image) let's choose the common x-Value in both sets of points. The inhomognious y-values are considered to be the same as the homogenious y-values (apporx.).
x11h = x11;
y11h = y11;
x12h = x11;
y12h = y12;
x21h = x21;
y21h = y21;
x22h = x21;
y22h = y22;
Now we get a system of equation that we can solve for the matrix coefficient. We set h00=1, since the matrix needs only to be determined up to a insignificant multiplicative factor.
h00 = 1;
coef = NSolve[{
x11 == (h00*x11h + h01*y11h + h02)/(h20*x11h + h21*y11h + h22),
y11 == (h10*x11h + h11*y11h + h12)/(h20*x11h + h21*y11h + h22),
x12 == (h00*x12h + h01*y12h + h02)/(h20*x12h + h21*y12h + h22),
y12 == (h10*x12h + h11*y12h + h12)/(h20*x12h + h21*y12h + h22),
x21 == (h00*x21h + h01*y21h + h02)/(h20*x21h + h21*y21h + h22),
y21 == (h10*x21h + h11*y21h + h12)/(h20*x21h + h21*y21h + h22),
x22 == (h00*x22h + h01*y22h + h02)/(h20*x22h + h21*y22h + h22),
y22 == (h10*x22h + h11*y22h + h12)/(h20*x22h + h21*y22h + h22)
},
{h01, h02, h10, h11, h12, h20, h21, h22}
]
projeMat =
Flatten[{{h00, h01, h02}, {h10, h11, h12}, {h20, h21, h22}} /. coef,
1];
The output has imaginary values ??
To remove the perspective distortion, we need to inverse the transformation matrix and apply it to the image:
invProjeMat = Inverse[projeMat];
ImageTransformation[notreDame, TransformationFunction[invProjeMat]]
...but this is not working?
Thanks for any help!!
ImageTransformation[]
,ImageForwardTransformation[]
, andImagePerspectiveTransformation[]
? (Maybe alsoFindGeometricTransform[]
andTransformationFunction[]
.) $\endgroup$