【问题标题】:Rotating an image without the Image Processing Toolbox在没有图像处理工具箱的情况下旋转图像
【发布时间】:2011-09-15 10:09:24
【问题描述】:

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

  • 不使用imrotate 函数,因为它是图像处理工具箱的一部分,
  • 带有loose参数,表示输出的大小与输入的图像大小不同,
  • imrotate 相比,功能不太慢。

我已经找到a function 来执行此操作(只需将imshowbestblk 替换为您自己的函数,以免使用工具箱),但它真的很慢对于大图像。我的方法会尽量避免循环并尽可能依赖interp2


函数的签名是:

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

地点:

  • interpolation 将是 bilinearbicubicnearest
  • 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 并在输入图像的角p 的坐标上调用rotate_points

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

【问题讨论】:

  • 令人惊讶的是,这个问题有 3k 的浏览量,但只有 4 次赞成,而答案只有 2 次赞成,尽管问题很清楚并且回答正确。

标签: matlab image-rotation


【解决方案1】:

对于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

【讨论】:

  • @wok:我刚刚看到你总是分别加减中心。如果您所有的网格网格都来自-s/2:s/2,或者您只是在我的解决方案中使用 1:szNew,这可能会更容易。
  • 太棒了!我可以重写 imrotate,但它比 Matlab 在 900x1000 图像上的 imrotate 慢。不过还是可以接受的! :)
  • 实际上,它比 maketform 的 Matlab 快,但比带有 Mex-file 的 Matlab 慢。我不知道是什么让官方imrotate选择了一个或另一个。
  • Mexfile 不用于bicubic 插值,也不用于double 而不是uint8 的图像。
猜你喜欢
  • 1970-01-01
  • 2018-12-30
  • 1970-01-01
  • 2021-12-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多