matlab image-processing octave homography projective-geometry

matlab - Cómo deformar una imagen usando puntos de control



image-processing octave (2)

Quiero convertir una imagen usando puntos de control de acuerdo con este esquema extraído de aquí :

A y B contiene las coordenadas de la fuente y los vértices de un objetivo.

Estoy computando la matriz de transformación como:

A = [51 228; 51 127; 191 127; 191 228]; B = [152 57; 219 191; 62 240; 92 109]; X = imread(''rectangle.png''); info = imfinfo(''rectangle.png''); T = cp2tform(A,B,''projective'');

Hasta aquí parece funcionar correctamente, porque (usando coordenadas normalizadas) un vértice fuente produce su vértice objetivo:

H = T.tdata.T; > [51 228 1]*H ans = -248.2186 -93.0820 -1.6330 > [51 228 1]*H/ -1.6330 ans = 152.0016 57.0006 1.0000

El problema es que imtransform produce un resultado inesperado:

Z = imtransform(X,T,''XData'',[1 info.Width], ''YData'',[1 info.Height]); imwrite(Z,''projective.png'');

¿Cómo puedo usar imtransform para producir este mi resultado esperado ?:

¿Hay alguna forma alternativa de lograrlo?


Debe "adaptar" los puntos de control al tamaño de la imagen con la que está trabajando. La forma en que lo hice es calculando una transformación afín entre las esquinas de los puntos de control en A y las esquinas de la imagen de origen (preferiblemente quiere hacer que los puntos estén en el mismo orden en el sentido de las agujas del reloj).

Una cosa que debo señalar es que el orden de los puntos en su matriz A no coincide con la imagen que ha mostrado, así que lo arreglé en el siguiente código ...

Aquí está el código para estimar la homografía (probado en MATLAB):

% initial control points A = [51 228; 51 127; 191 127; 191 228]; B = [152 57; 219 191; 62 240; 92 109]; A = circshift(A, [-1 0]); % fix the order of points to match the picture % input image %I = imread(''peppers.png''); I = im2uint8(checkerboard(32,5,7)); [h,w,~] = size(I); % adapt control points to image size % (basically we estimate an affine transform from 3 corner points) aff = cp2tform(A(1:3,:), [1 1; w 1; w h], ''affine''); A = tformfwd(aff, A); B = tformfwd(aff, B); % estimate homography between A and B T = cp2tform(B, A, ''projective''); T = fliptform(T); H = T.tdata.Tinv

Yo obtengo:

>> H H = -0.3268 0.6419 -0.0015 -0.4871 0.4667 0.0009 324.0851 -221.0565 1.0000

Ahora visualicemos los puntos:

% check by transforming A points into B %{ BB = [A ones(size(A,1),1)] * H; % convert to homogeneous coords BB = bsxfun(@rdivide, BB, BB(:,end)); % convert from homogeneous coords %} BB = tformfwd(T, A(:,1), A(:,2)); fprintf(''error = %g/n'', norm(B-BB)); % visually check by plotting control points and transformed A figure(1) subplot(121) plot(A([1:end 1],1), A([1:end 1],2), ''.-'', ''MarkerSize'',20, ''LineWidth'',2) line(BB([1:end 1],1), BB([1:end 1],2), ''Color'',''r'', ''Marker'',''o'') text(A(:,1), A(:,2), num2str((1:4)'',''a%d''), ... ''VerticalAlign'',''top'', ''HorizontalAlign'',''left'') title(''A''); legend({''A'', ''A*H''}); axis equal ij subplot(122) plot(B([1:end 1],1), B([1:end 1],2), ''.-'', ''MarkerSize'',20, ''LineWidth'',2) text(B(:,1), B(:,2), num2str((1:4)'',''b%d''), ... ''VerticalAlign'',''top'', ''HorizontalAlign'',''left'') title(''B''); legend(''B''); axis equal ij

Finalmente podemos aplicar la transformación en la imagen fuente:

% transform input image and show result J = imtransform(I, T); figure(2) subplot(121), imshow(I), title(''image'') subplot(122), imshow(J), title(''warped'')


Su problema es que recortó accidentalmente la imagen de salida cuando especificó su XData e YData en imtransform . Una opción sería usar tformfwd con para transformar A para calcular los XData válidos de XData e YData .

[U,V] = tformfwd(T, A(:,1), A(:,2)); Z = imtransform(X,T,''XData'',[min(U) max(U)], ''YData'', [min(V) max(V)]);