8

Matlabを使用して非正方形の画像を回転させたい:

  • imrotateこの関数はImageProcessingToolboxの一部であるため、使用せずに、
  • looseパラメータを使用すると、出力のサイズが入力画像のサイズと異なることを意味します。
  • と比較して遅すぎない機能を備えていimrotateます。

これを行うための関数をすでに見つけました(ツールボックスを使用しないように、独自の関数に置き換えimshowてください)が、大きな画像の場合は非常に遅くなります。私のアプローチは、ループを作成したり、にできるだけ依存したりすることを避けようとします。bestblkinterp2


関数のシグネチャは次のようになります。

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

どこ:

  • interpolationbilinearbicubicまたはnearest、_
  • bboxcrop、またはになりlooseます。

作物

パラメータですでに良い結果が得られてい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_pointsp

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バージョンの場合、必要なパディングの量を確認するだけです。少しのジオメトリで簡単に見積もることができます。

「ゆるい」長方形を描くと、基本的に元の長方形に4つの直角三角形が追加されます。三角形のhypotenuseは、長方形の辺です。他の2つの辺を決定できれば、新しい辺の長さ、つまりパディングを簡単に計算できます。幸いなことに、直角三角形の角度の1つは、まさに回転角です。

結局のところ、パディングを明示的に計算する必要はありません。「ゆるい」画像のサイズを持つ、より大きな配列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 に答える