具有手风琴效果的图像 [英] Image with accordion effect

查看:106
本文介绍了具有手风琴效果的图像的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已将图像文件读入MATLAB,并且试图在一个方向上将其拉伸,但是数量可变(正弦).这会在图像上产生手风琴效果.我玩弄了imresize,但是只能线性调整图像大小.我希望每个图像行的拉伸"量有所不同.我尝试通过以下代码传达这一点:

I have read in an image file to MATLAB and I am trying to stretch it in one direction, but a variable amount (sinusoidal). This would create an accordion affect on the image. I have toyed around with imresize, however that only resizes the image linearly. I would like the amount of "stretch" to vary for each image line. I tried to convey this with the following code:

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

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

You can see that segments of the image are stretched, then compressed, then stretched, etc, like an accordion. However, each segment has a uniform amount of stretch, whereas I'd like it to be increasing then decreasing as you move along the image.

我还查看了

I have also looked at MATLAB's example of Applying a Sinusoidal Transformation to a Checkerboard which seems very applicable to my problem, however I have been trying and I cannot get this to produce the desired result for my image. Any help is much appreciated.


UPDATE:

Thank you for Answer #1. I was unable to get it to work for me, but also realized it would resulted in loss of data, as the code only called for certian lines in the original image, and other lines would have been ignored.

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

After experimenting further, I developed the code below. I used a checkerboard as an example. While combersome, it does get the job done. However, upon trying the script with an actual high-resolution image, it was extremely slow and ended up failing due to running out of memory. I believe this is because of the excessive number of "imresize" commands that are used in loop.

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

有人知道实现这一目标的更简单方法吗?如果运行上面的代码,则可以看到我试图达到的效果.不幸的是,我上面的方法不允许我调整拉伸"的幅度,只能调整周期"的数量或频率.帮助也将不胜感激.非常感谢!

Does anyone know of a simpler way to achieve this? If you run the code above, you can see the effect I am trying to achieve. Unfortunately, my method above does not allow me to adjust the amplitude of the "stretch" either, only the number of "cycles," or frequency. Help on this would also be appreciated. Much thanks!

推荐答案

这是我的处理方式:

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

  1. Determine how the coordinate of each point in your Final image F maps into your Initial image I of size (M,N)

由于您只想水平拉伸,因此在最终图像中给定一个点(xF,yF),则该点将在初始图像中为(xI,yI),可以按以下方式获得xI和yI:

Since you want to stretch horizontally only, given a point (xF,yF) in your final image, that point would be (xI,yI) in your initial image where xI and yI can be obtained as follows:

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

yI = yF;
xI = xF + Lsin(xFK);

注意:

  • 这些等式不能保证xI保持在[1:N]范围内,因此需要添加修剪
  • K控制要在手风琴效果中产生多少皱纹.例如,如果您只想要一个皱纹,则K为2 * pi/N
  • L控制您要应用的拉伸程度

然后使用在1中进行的转换,简单地从图像I中表达图像F.

Then simply express your image F from image I with the transforms you have in 1.

将所有内容放在一起,下面的代码创建一个样本图像I并生成图像F,如下所示:

Putting it all together, the code below creates a sample image I and generates the image F as follows:

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

如果运行此确切代码,则会得到:

If you run this exact code you get:

如您所见,右侧的最终图像将左侧图像的中央部分拉伸,使您的手风琴效果具有皱纹.

As you can see, the final image on the right stretches the center part of the image on the left, giving you an accordion effect with one wrinkle.

您可以摆弄K和L并调整公式以获得所需的确切效果,但是请注意,如何通过以矩阵形式表示转换来实现MATLAB在不到一秒的时间内执行代码.如果有一个好处,那就是您应该尽可能避免循环和复杂处理.

You can fiddle with K and L and adjust the formula to get the exact effect you want, but note how by expressing the transform in a matrix form MATLAB executes the code in a fraction of second. If there is one take away for you is that you should stay away from for loops and complex processing whenever you can.

玩得开心!

这篇关于具有手风琴效果的图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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