基于不同方向给出的线条扭曲图像

时间:2011-05-30 19:36:26

标签: matlab line computer-vision interpolation geometry

我想根据不同方向给出的线条来扭曲图像:

  1. 对于输入图像上的每一行,我可以得到行上像素的坐标
  2. 然后我会将这些像素映射到变形图像,以便每一行现在都是一列。
  3. 我会使用interp2,因为我已经有XYZ,我会使用XiYi为每一行获得的坐标。但是,你会怎么做:

    • 避免进行for循环,哪个索引遍布行数?
    • 确保输出变形图像中的每列都具有相同的大小?
    • 使用径向线对输入图像进行采样?
    • 在我看来最困难的问题是,即使我使用不同的方向,你如何保持邻域结构:例如,输入图像左侧部分的horiontal线(行)和右侧部分的径向线?

    这里的输入图像是轮胎,有这种漂亮的圆圈图案。我可以从轮胎的中心做出径向线,我想得到一个新的图像,其列是径向线的像素。

    这是我到目前为止的代码(没有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');
    

    以下是不同的输出:

    Examples

    Lines

    Circles


    这是扭曲的图像: Warped image

    以下是答案的代码:

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

2 个答案:

答案 0 :(得分:3)

你的主要问题(我认为)是构建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)

输出将严重失真(当然),因为每个半径的圆被拉伸到相同的长度。沿线变形将是最小的。如果一切顺利且我的数学没有离开我,这应该给你一个轮胎的展开图像,从中心到右边切割。

答案 1 :(得分:2)

最好的方法: 使用二阶多项式变换将所有圆转换为线,然后剪切出您需要的线。 使用2个matlab命令cp2tform()和参数'polynomial'和imtransform() 在变换T内设置x ^ 2和y ^ 2的值1以创建圆和平移以定义轮胎的中心像素。

很抱歉,我不提供代码,因为我从iPhone回答。 附:检查Matlab有关多项式和保形变换的帮助。他们完全符合您的需要。