根据不同方向的线条扭曲图像
我想根据不同方向的线条来扭曲图像:
- 对于输入图像上的每条线,我可以获得该线上像素的坐标,
- 然后将这些像素映射到扭曲的图像,以便每条线现在都是一个专栏。
我会使用 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');
I would like to warp an image based on lines given with different orientations:
- for each line on the input image, I can get the coordinates of the pixels on the line
- then I would map these pixels to the warped image so that each line is now a column.
I would use interp2
since I already have X
, Y
and Z
, and I would make Xi
and Yi
with the coordinates obtained for each line. However, how would you:
- avoid making a
for
loop which index goes all over the number of lines? - make sure each column in the output warped image is the same size?
- sample the input image with radial lines?
- the hardest question in my opinion, how would you keep the neighbourhood structure even if I use different orientations : for instance, the horiontal lines (rows) of the left part of the input image, and the radial lines for the right part?
The input image here is a tire, there is this nice pattern of circles. I could make radial lines from the center of the tire and I would like to get a new image whose columns are the pixels from the radial lines.
Here is the code I have so far (no interp2
yet as I have not solved the problems explained above).
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');
Here are different outputs:
Here is the warped image:
Here is the code from the answer:
[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');
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
你的主要问题(我认为)是构建 interp2。您可以通过认识到在新图像中水平轴代表直线的角度,垂直轴代表距圆心的距离来构造这些,以便构造这些:
输出将严重扭曲(当然),因为每个半径处的圆被拉伸为相同的长度。沿着这条线,失真将是最小的。如果一切顺利并且我的数学能力还没有离开我,这应该会给你一个轮胎的展开图像,沿着从中心到右侧的线切割。
Your main problem (I think) is constructing matrices XI and YI needed for interp2. You construct these by realising that in your new image the horizontal axis represents the angle of the line, and the vertical axis represents the distance from the centre of the circle so to construct those:
The output will be heavily distorted (of course) because the circle at each radius is stretched to be the same length. Along the lines distortion will be minimal. If all goes well and my math-fu hasn't left me this should give you a rolled out image of the tire, cut on the line from the centre to the right.
最好的办法:
使用二阶多项式变换将所有圆变换为直线,然后剪出您需要的直线。
使用 2 个带有参数“多项式”的 Matlab 命令 cp2tform() 和 imtransform()
在变换 T 内设置 x^2 和 y^2 的值 1 以创建圆并进行平移以定义轮胎的中心像素。
抱歉,我不提供代码,因为我是通过 iPhone 接听的。
Ps 检查 Matlab 有关多项式和保角变换的帮助。他们正是按照您的需要做的。
The best way:
Use polynomial transformation of second order to transform all the circles to lines and then just cut out the lines you need.
Use 2 Matlab commands cp2tform() with parameter 'polynomial' and imtransform()
Set inside the transformation T the values 1 for x^2 and y^2 to create a circle and translation to define the center pixel of the tire.
Sorry that I don't supply code, since I answer from iPhone.
P.s. Check Matlab help about polynomial and conformal transformation. They do exactly what you need.