问题描述
|
我想根据以不同方向给出的线对图像进行变形:
对于输入图像上的每一行,我可以获取该行上像素的坐标
然后将这些像素映射到变形的图像,以便现在每行都是一列。
我将使用
interp2
,因为我已经有了X
,Y
和Z
,并且我将使Xi
和Yi
以及每行获得的坐标。但是,您将如何:
避免进行for
循环,哪个索引遍及行数?
确保输出的扭曲图像中的每一列都具有相同的大小?
用径向线采样输入图像?
我认为最棘手的问题是,即使我使用不同的方向,您如何保持邻域结构:例如,输入图像左侧的水平线(行)和右侧的径向线?
这里的输入图像是轮胎,有这种漂亮的圆圈图案。我可以从轮胎的中心绘制径向线,我想获得一个新图像,其列为径向线的像素。
这是我到目前为止的代码(尚没有interp2
,因为我还没有解决上面说明的问题)。
close all
%% Image
Z = imread(\'tire.tif\');
% The corresponding mesh
sz = size(Z);
[X,Y] = meshgrid(1:sz(2),1:sz(1));
%% Line
lineEquation = @(c,v) (v(1)*(X-c(2))+v(2)*(Y-c(1)))/norm(v);
getLine = @(c,v) abs(lineEquation(c,v))<1/2;
% Example
c = [93,109];
v = [2,1];
line = getLine(c,v);
%% Circle
circleEquation = @(c,r) ((X-c(2)).^2+(Y-c(1)).^2-r^2)/r^2;
getCircle = @(c,r) abs(circleEquation(c,r))<1/r;
% Example
r = 24;
circle = getCircle(c,r);
%% Plot a sequence of line
figure;
for delta = -1:0.1:1
v = [0.1,delta];
line_delta = getLine(c,v);
Z_line = Z;
Z_line(line_delta) = 255;
imagesc(Z_line);
colormap(\'gray\');
pause(0.05);
end
%% Plot examples
figure;
subplot(221);
imagesc(Z);
title(\'Image\');
subplot(222);
Z_line = Z;
Z_line(line) = 255;
imagesc(Z_line);
title(\'Line\');
subplot(223);
Z_circle = Z;
Z_circle(circle) = 255;
imagesc(Z_circle);
title(\'Circle\');
subplot(224);
% Todo
title(\'Warped image\');
colormap(\'gray\');
这是不同的输出:
这是变形的图像:
这是答案中的代码:
[ANG,RAD] = meshgrid(0:0.01:2*pi,0:0.5:166);
XI = c(2) + cos(ANG).*RAD;
YI = c(1) + sin(ANG).*RAD;
WARPED = interp2(X,Y,double(Z),XI,YI);
WARPED(isnan(WARPED))= max(WARPED(:));
imagesc(WARPED);
title(\'Warped image\');
colormap(\'gray\');
解决方法
您的主要问题(我认为)是构造interp2所需的矩阵XI和YI。通过实现新图像中的水平轴代表线的角度,垂直轴代表距圆心的距离来构造它们,从而构造这些点:
%% angle from 360 to 0,radius from 0 to 100
%% resulting image will be 361 x 101 pixels
[ANG,RAD] = meshgrid(360:-1:0,0:100);
%% I take the centre of the circle at (93,109) Is this correct?
%% From there you can create XI and YI
%% from the angle and radius you have at each point
XI = ones(size(ANG))*93 + cos(ANG/(2*PI)).*RAD;
YI = ones(size(ANG))*109 + sin(ANG/(2*PI)).*RAD;
WARPED = interp2(X,Y,Z,XI,YI)
输出将严重失真(当然),因为每个半径处的圆都被拉伸为相同的长度。沿线失真将是最小的。如果一切顺利,而我的数学能力还没有离开我,这应该可以为您提供轮胎的图像,从中心到右侧的直线上截取。
, 最好的方法:
使用二阶多项式变换将所有圆变换为直线,然后仅剪切出所需的直线。
使用2个Matlab命令cp2tform()和参数\'polynomial \'和imtransform()
在变换T内设置x ^ 2和y ^ 2的值1以创建一个圆并平移以定义轮胎的中心像素。
很抱歉,我没有提供代码,因为我是从iPhone回答的。
P.s.查看Matlab帮助,了解多项式和保形变换。他们正是您需要的。