手风琴效果的图像

时间:2013-03-07 23:21:20

标签: image matlab transformation stretch

我已经在图像文件中读到MATLAB,我试图在一个方向上拉伸它,但是可变量(正弦曲线)。这会对图像产生手风琴效果。我玩弄了一下,但是只能线性调整图像大小。我希望每个图像线的“拉伸”量不同。我尝试使用以下代码传达此信息:

periods = 10; % Number of "stretch" cycles
sz = size(original_image,2)/periods;
s = 0;
x = 0;
for index = 1:periods
    B = original_image(:,round(s+1:s+sz));
    if mod(index,2) == 0
        amp = 1.5;
    else
        amp = 0.75;
    end
    xi = size(B,2)*amp;
    new_image(:,x+1:x+xi) = imresize(B, [size(B,1) size(B,2)*amp]);
    s = s + sz;
    x = x+xi;
end

您可以看到图像的片段被拉伸,然后压缩,然后拉伸等,就像手风琴一样。但是,每个片段都具有均匀的拉伸量,而我希望它随着您沿图像移动而增加然后减小。

我还看过MATLAB的Applying a Sinusoidal Transformation to a Checkerboard示例,它似乎非常适用于我的问题,但是我一直在努力,我不能让它为我的图像产生所需的结果。 任何帮助深表感谢。

<小时/> 更新:

谢谢你的答案#1。我无法让它为我工作,但也意识到它会导致数据丢失,因为代码只调用原始图像中的certian行,而其他行将被忽略。

经过进一步的实验,我开发了以下代码。我以棋盘格为例。虽然精简,但它确实完成了工作。但是,在使用实际的高分辨率图像尝试脚本时,它非常慢并且由于内存不足而最终失败。我相信这是因为循环中使用了过多的“imresize”命令。

I = checkerboard(10,50);
I = imrotate(I,90);
[X Y] = size(I);
k = 4; % Number of "cycles"
k = k*2;
x = 1;
y = 2;
z = 2;
F = [];
i = 1;
t = 0;
s = 0;

for j = 1:k/2
    t = t + 1;
    for inc = round(s+1):round(Y/k*t)
        Yi = i + 1;
        F(:,(x:y)) = imresize(I(:,(inc:inc)),[X Yi]);
        x = y + 1;
        y = x + z;
        z = z + 1;
        i = i + 1;
    end
    y = y - 2;
    z = z - 4;
    for inc = round(Y/k*t+1):round(Y/k*(t+1))
        Yi = i - 1;
        F(:,(x:y)) = imresize(I(:,(inc:inc)),[X Yi]);
        x = y + 1;
        y = x + z;
        z = z - 1;
        i = i - 1;
    end
    y = y + 2;
    z = z + 4;

    s = Y/k*(t+1);
    t = t + 1;
end
Fn = imresize(F, [X Y]);
imshow(Fn);

有谁知道更简单的方法来实现这一目标?如果你运行上面的代码,你可以看到我想要实现的效果。不幸的是,我上面的方法不允许我调整“拉伸”的幅度,只调整“周期”或频率的数量。对此的帮助也将不胜感激。非常感谢!

1 个答案:

答案 0 :(得分:1)

以下是我将如何处理它:

  1. 确定最终图像F中每个点的坐标如何映射到尺寸为(M,N)的初始图像I

    由于您只想在最终图像中给定一个点(xF,yF),所以在初始图像中该点(xI,yI)可以获得xI和yI,如下所示:

    yI = yF;
      xI = xF + L sin(xF K);

    注意:

    • 这些方程不保证xI保持在[1:N]范围内,因此需要添加裁剪
    • K控制手风琴效果中想要的皱纹数量。例如,如果您只想要一个皱纹,K将是2 * pi / N
    • L控制您想要应用的伸展量
  2. 然后只使用1中的变换从图像I表达图像F.

  3. 总而言之,下面的代码创建了一个示例图像I并生成图像F,如下所示:

      % Generate a sample input image
      N=500;
      xF=1:N;
      I=(1:4)'*xF/N*50;
    
      % Set the parameters for your accordion transform
      K=2*pi/N;
      L=100;
    
      % Apply the transform
      F=I(:, round(min(N*ones(1,N), max(ones(1,N), (xF + L*sin(xF*K))))) );
    
      % Display the input and output images side by side
      image(I);
      figure;
      image(F);
    

    如果你运行这个确切的代码,你会得到:

    enter image description here

    如您所见,右侧的最终图像会拉伸左侧图像的中央部分,为您带来一个皱纹的手风琴效果。

    你可以摆弄K和L并调整公式以获得你想要的精确效果,但要注意如何通过以矩阵形式表达变换MATLAB在几分之一秒内执行代码。如果有一个收获就是你应该尽可能远离循环和复杂的处理。

    玩得开心!