使用控制点扭曲图像 [英] Warping an image using control points

查看:309
本文介绍了使用控制点扭曲图像的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想根据从



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,'投射');

到此为止它似乎正常工作,因为(使用标准化坐标)源顶点产生其目标vertex:

  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中测试):

 %初始控制点
A = [51 228; 51 127; 191 127; 191 228];
B = [152 57; 219 191; 62 240; 92 109];
A = circshift(A,[ - 0 0]); %修复匹配图片的点数顺序

%输入图片
%I = imread('peppers.png');
I = im2uint8(棋盘格(32,5,7));
[h,w,〜] = size(I);

%将控制点调整为图像大小
%(基本上我们从3个角点估计仿射变换)
aff = cp2tform(A(1:3,:),[ 1 1; w 1; wh],'仿射');
A = tformfwd(aff,A);
B = tformfwd(aff,B);

%估计A和B之间的单应性b
T = cp2tform(B,A,'投射');
T = fliptform(T);
H = T.tdata.Tinv

我得到:

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

现在让我们想象点数:

 通过将A点转换为B $来进行%检查b $ b%{
BB = [一个(大小(A,1),1)] * H; %转换为同质coords
BB = bsxfun(@rdivide,BB,BB(:,end)); %转换为同质coords
%}
BB = tformfwd(T,A(:,1),A(:,2));
fprintf('error =%g \ n',norm(B-BB));

%通过绘制控制点进行目视检查并转换A
数字(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:结束1],2),'颜色','r','标记','o')
文本(A(:,1),A(:,2),num2str(( 1:4)','a%d'),...
'RevertAlign','top','Horizo​​ntalAlign','left')
title('A');传说({'A','A * H'});轴等于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','Horizo​​ntalAlign','left')
title('B');图例( B);轴等于ij



最后我们可以在源图像上应用转换:

 %转换输入图像并显示结果
J = imtransform(I,T);
figure(2)
subplot(121),imshow(I),title('image')
subplot(122),imshow(J),title('warped')


I want to convert an image using control points according to this scheme extracted from here:

A and B contains the coordinates of the source an target vertices.

I am computing the transformation matrix as:

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');

Up to here it seems to properly work, because (using normalized coordinates) a source vertex produces its target vertex:

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

The problem is that imtransform produces an unexpected result:

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

How can I use imtransform to produce this my expected result?:

Is there an alternative way to achieve it?

解决方案

You have to "adapt" the control points to the size of the image you're working with. The way I did this is by computing an affine transformation between the corners of the control points in A and the corners of the source image (preferrably you want to make the points are in the same clockwise order).

One thing I should point out is that the order of points in your matrix A does not match the picture you've shown, so I fixed that in the code below...

Here is the code to estimate the homography (tested in 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

I get:

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

Now let's visualize the points:

% 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

Finally we can apply the transformation on the source image:

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

这篇关于使用控制点扭曲图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆