Matlab 使用控制点扭曲图像

Matlab 使用控制点扭曲图像,matlab,image-processing,octave,homography,projective-geometry,Matlab,Image Processing,Octave,Homography,Projective Geometry,我想根据此方案使用控制点转换图像,该方案提取自: A和B包含源顶点和目标顶点的坐标 我将转换矩阵计算为: 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'); 到目前为止,它似乎正常工作,因为(使用

我想根据此方案使用控制点转换图像,该方案提取自:

A
B
包含源顶点和目标顶点的坐标

我将转换矩阵计算为:

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');
到目前为止,它似乎正常工作,因为(使用标准化坐标)源顶点生成其目标顶点:

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
问题在于
imtransform
会产生意外的结果:

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

我如何使用
imtransform
生成我预期的结果

是否有其他方法可以实现此目标?

您必须根据正在处理的图像的大小“调整”控制点。我这样做的方法是通过计算
A
中控制点的角点与源图像的角点之间的仿射变换(最好是使点按相同的顺时针顺序排列)

我要指出的一点是,矩阵
A
中的点顺序与您显示的图片不匹配,因此我在下面的代码中修复了这一点

以下是估计单应性的代码(在MATLAB中测试):

我得到:

>> H
H =
   -0.3268    0.6419   -0.0015
   -0.4871    0.4667    0.0009
  324.0851 -221.0565    1.0000
现在让我们设想一下要点:

% 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

最后,我们可以对源图像应用变换:

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

您的问题是,当您在
imtransform
中指定
XData
YData
时,意外地剪切了输出图像。一个选项是使用
tformfwd
与转换
A
来计算有效的
XData
YData
范围

[U,V] = tformfwd(T, A(:,1), A(:,2));

Z = imtransform(X,T,'XData',[min(U) max(U)], 'YData', [min(V) max(V)]);

我对matlab了解不够,尤其是不知道代码中
tdata
的含义。但就我个人而言,我会尝试在matlab中或使用单独的工具手动复制,以检查计算出的矩阵是否有意义。请注意,投影变换矩阵仅定义为一个标量因子,因此在比较它们之前,请相应地缩放矩阵。如果矩阵一致,问题在于应用它们,否则问题在于找到它们。你看过
imtransform
的演示吗?(在倍频程提示下运行
demo imtransform
)。如果你看一下,你的问题正好是第一个演示的第六个数字。你的问题是当你做Z=imtransform(X,T,'XData',[1信息宽度],'YData',[1信息高度])时裁剪输出图像;使用带有A的tformfwd来计算扩展数据和YData范围。谢谢您,使用[U,V]裁剪区域,imtransform裁剪该区域。但是,输出图片仍然是上述错误图片(使用[U,V]坐标裁剪):
[U,V] = tformfwd(T, A(:,1), A(:,2));

Z = imtransform(X,T,'XData',[min(U) max(U)], 'YData', [min(V) max(V)]);