In the past, I also wrote perspective transformations. At that time, the algorithm was so weak that I would actually use two transformations. However, the three articles cited are all very good articles that I have not understood until today. The so-called tilt correction must have a calibration point to change a skewed rectangle into a non-skewed one. Therefore, a transformation matrix can be obtained from the four points of the original quadrilateral and the four points of the new rectangle, and then applied to the Global Image Based on this matrix. The detailed principle is here. For MIT, I will not be better than what he introduced. It is better to read the original version.
The code here is fully implemented according to the principles of the MIT article. However, due to the MATLAB details, I switched the positions of x and y in the formula:
Clear all; close all; clc; IMG = imread('rect.bmp '); IMG = rgb2gray (IMG); imshow (mat2gray (IMG); [m n] = size (IMG ); dot = ginput (); % Take four vertices, in turn top left, top right, bottom left, bottom right. Here I take the four corners of the book W = round (SQRT (dot) -dot (2, 1) ^ 2 + (dot (1, 2)-dot (2, 2) ^ 2 )); % obtain the new rectangle width from the original quadrilateral H = round (SQRT (dot ()-dot () ^ 2 + (dot ()-dot )) ^ 2); % obtain the new rectangle height from the original quadrilateral y = [dot ()]; % four original vertex x = [dot ()]; % here is the new vertex, my rectangle, it can also be made into another shape %. The source image can be like a rectangle, and the new image is like any quadrilateral composed of points obtained from the dot. :) y = [dot (1, 1) dot (1, 1) dot (1, 1) + H dot (1, 1) + H]; X = [dot (1, 2) dot (1, 2) + W dot (1, 2) dot (1, 2) + W]; B = [x (1) y (1) x (2) y (2) x (3) Y (3) x (4) y (4)] '; % the four vertices after transformation, and the value on the right of the equation % simultaneous equations, the coefficient of the equation A = [x (1) y (1) 1 0 0 0-x (1) * x (1)-x (1) * Y (1 ); 0 0 0 x (1) y (1) 1-y (1) * x (1)-y (1) * Y (1); X (2) Y (2) 1 0 0 0-X (2) * X (2)-X (2) * Y (2); 0 0 0 x (2) y (2) 1-y (2) * X (2)-y (2) * Y (2); X (3) y (3) 1 0 0 0-X (3) * X (3)-X (3) * Y (3); 0 0 0 x (3) y (3) 1-y (3) * X (3) -Y (3) * Y (3); X (4) y (4) 1 0 0 0-X (4) * X (4)-X (4) * Y (4); 0 0 0 x (4) y (4) 1-y (4) * X (4)-y (4) * Y (4)]; fa = inv (a) * B; % the solution of the equation obtained by four points is also the global transformation coefficient A = FA (1); B = FA (2 ); C = FA (3); D = FA (4); E = FA (5); F = FA (6); G = FA (7 ); H = FA (8); rot = [d e f; a B C; G H 1]; % in the formula, the first number is X, and the first value is Y in MATLAB, therefore, rows 1 and 2 in the matrix are replaced with pix1 = rot * [1 1] '/(g * 1 + H * 1 + 1 ); % The upper left point of the transformed image, pix2 = rot * [1 N 1] '/(g * 1 + H * n + 1 ); % The upper right point of the transformed image, pix3 = rot * [M 1] '/(g * m + H * 1 + 1 ); % The lower left point of the transformed image, pix4 = rot * [m n 1] '/(g * m + H * n + 1 ); % Height = round (max ([pix1 (1) pix2 (1) pix3 (1) pix4 (1)])-min ([pix1 (1) pix2 (1) pix3 (1) pix4 (1)]); % height width = round (max ([pix1 (2) pix2 (2) pix3 (2) pix4 (2)])-min ([pix1 (2) pix2 (2) pix3 (2) pix4 (2)]); % imgn = zeros (height, width); delta_y = round (ABS (min ([pix1 (1) pix2 (1) pix3 (1) pix4 (1)]); % get the offset of the negative axis exceeding the y direction delta_x = round (ABS (min ([pix1 (2) pix2 (2) pix3 (2) pix4 (2)]); % get the offset inv_rot = inv (ROT); for I = 1-delta_y: height-delta_y % reverse lookup the original image point from the transformed image to avoid holes, the same as the rotation amplification principle for J = 1-delta_x: width-delta_x pix = inv_rot * [I J 1] '; % calculate the coordinates in the original image. Because [yw xw w] = fa * [Y x 1], [yw xw] is used here. W = Gy + HX + 1; pix = inv ([g * pix (1)-1 H * pix (1); G * pix (2) H * pix (2) -1]) * [-pix (1)-pix (2)] '; % is equivalent to solution [pix (1) * (GY + HX + 1) pix (2) * (GY + HX + 1)] = [Y x], such an equation is used to calculate y and X, and finally the PIX = [Y x]; If pix (1)> = 0.5 & pix (2)> = 0.5 & pix (1) <= M & pix (2) <= n imgn (I + delta_y, J + delta_x) = IMG (round (pix (1), round (pix (2); % the nearest neighbor interpolation, you can also use bilinear or bilinecoder interpolation end endfigure; imshow (uint8 (imgn ));
Program effect:
Source image. This is a good book.
After tilt correction
In the future, it may be possible to automatically correct it by combining the sift operator and the Hoff transform.
Note: There is a bug in the blog garden. When you copy the code in the lower left corner of the Code, the first column of line 2, 4, 6, and 8 of matrix A will copy less than 0.