8

我想用 Matlab 旋转一个非平方的图像:

  • 不使用该imrotate功能,因为它是图像处理工具箱的一部分,
  • 带有loose参数,这意味着输出的大小与输入图像的大小不同,
  • 并且与 相比具有不太慢的功能imrotate

我已经找到了一个函数来做到这一点(只需用你自己的函数替换imshowbestblk,以便不使用工具箱),但是对于大图像来说它真的很慢。我的方法会尽量避免产生循环并尽可能多地依赖interp2.


该函数的签名将是:

imOutput = my_imrotate(imInput, theta_degres, interpolation, bbox)

在哪里:

  • interpolation将是bilinear,bicubicnearest,
  • bbox将是croploose

庄稼

我已经对参数有了很好的结果crop,但是我无法找到loose参数的偏移量。

这是crop参数的代码,其中Z是输入,Zi是输出:

Z = double(imInput);
sz = size(Z);
[X,Y] = meshgrid(1:sz(2), 1:sz(1));
%# Center
c = sz(end:-1:1)/2;
%# Angle
t = theta_degres*pi/180;
%# Rotation
ct = cos(t);
st = sin(t);
Xi = c(1) + ct*(X-c(1))-st*(Y-c(2));
Yi = c(2) + st*(X-c(1))+ct*(Y-c(2));
%# Rotation
Zi = interp2(X, Y, Z, Xi, Yi);

松动的

我的想法是计算包含原始图像和旋转图像的帧的大小,然后:

  1. 填充原始图像,以获得尺寸为框架大小的图像,
  2. interp2在填充图像上使用,
  3. 裁剪生成的图像,以使旋转后的图像没有剩余的填充。

为了使用参数获取旋转图像的大小loose,我计算rotation_matrix并调用输入图像rotate_points角的坐标:p

rotation_matrix = [ct, -st; st, ct];
rotate_points = @(p) bsxfun(@plus, c', rotation_matrix * bsxfun(@minus, p, c)')';

任何帮助将不胜感激。


编辑:使用下面答案中提供的解决方案和以下代码,它似乎工作得很好:

%# See the answer below
[sz1,sz2] = size(Z);
sz1New = sz1*cos(t)+sz2*sin(t);
sz2New = sz2*cos(t)+sz1*sin(t);
[Xi,Yi] = meshgrid(-(sz2New-1)/2:(sz2New-1)/2,-(sz1New-1)/2:(sz1New-1)/2);
%# now all that's left is rotating Xi,Yi - I have already subtracted the center

%# My little piece of additional code
Xii = (1+sz2)/2 + ct*Xi - st*Yi;
Yii = (1+sz1)/2 + st*Xi + ct*Yi; 
Zi = interp2(X, Y, Z, Xii, Yii);
4

1 回答 1

4

对于该loose版本,您需要做的就是找出您需要多少填充。你可以用一点几何图形轻松估计它:

如果您绘制“松散”矩形,则实际上是在原始矩形上添加了四个直角三角形。三角形的斜边是矩形的边。如果您可以确定其他两侧,则可以轻松计算新边的长度,从而计算填充。幸运的是,直角三角形的角度之一正是您的旋转角度。

事实证明,您甚至不需要显式计算填充 - 您只需创建一个具有“松散”图像大小的更大数组 Xi,Yi。

因此:

[sz1,sz2] = size(Z);
sz1New = sz1*cos(t)+sz2*sin(t);
sz2New = sz2*cos(t)+sz1*sin(t);
[Xi,Yi] = meshgrid(-(sz2New-1)/2:(sz2New-1)/2,-(sz1New-1)/2:(sz1New-1)/2);
%# now all that's left is rotating Xi,Yi - I have already subtracted the center
于 2011-06-15T12:14:32.857 回答