メインコンテンツ

イメージの回転とスケーリングの自動検出

この例では、2 つのイメージの間に見られる幾何学的変換を自動的に判定する方法を説明します。具体的には、回転やスケーリングにより 1 つのイメージが別のイメージに対して歪んでいる場合、関数 detectSURFFeatures および estimateGeometricTransform2D を使用して回転角度とスケール係数を特定することができます。その後、これらのパラメーターを使用して、歪んだイメージを元の外観に戻すことができます。

イメージの読み取り

イメージをワークスペースに読み込みます。

original = imread("cameraman.tif");
imshow(original);
text(size(original,2),size(original,1)+15, ...
    "Image courtesy of Massachusetts Institute of Technology", ...
    FontSize=7,HorizontalAlignment="right");

イメージのサイズ変更と回転

スケール係数を変更します。

scale = 0.7;
J = imresize(original,scale);

% Adjust the rotation angle, |theta|. The function |imrotate| rotates images
% counterclockwise for positive values of |theta|. To rotate the image
% clockwise, use a negative value for |theta|.
theta = 30;
distorted = imrotate(J,-theta);
figure
imshow(distorted)

入力イメージに対してさまざまなスケールや回転を試すと結果が向上する可能性があります。ただし、スケールを極端に変化させると、特徴検出器が正確な解析を行うのに必要な特徴を認識できなくなる可能性があります。

イメージ間で一致する特徴の検出

両方のイメージで特徴を検出します。

ptsOriginal = detectSURFFeatures(original);
ptsDistorted = detectSURFFeatures(distorted);

元の特徴と歪んだ特徴から特徴記述子を抽出します。

[featuresOriginal,validPtsOriginal] = extractFeatures(original,ptsOriginal);
[featuresDistorted,validPtsDistorted] = extractFeatures(distorted,ptsDistorted);

その記述子を使用して特徴をマッチングします。

indexPairs = matchFeatures(featuresOriginal,featuresDistorted);

各イメージについて対応するポイントの位置を取得します。

matchedOriginal = validPtsOriginal(indexPairs(:,1));
matchedDistorted = validPtsDistorted(indexPairs(:,2));

推定的なポイントのマッチを表示します。

figure
showMatchedFeatures(original,distorted,matchedOriginal,matchedDistorted);
title("Putatively matched points (including outliers)");

変換の推定

RANSAC をロバストにした M-estimator Sample Consensus (MSAC) アルゴリズムを使用して、一致する点のペアに基づいて変換を特定します。このアルゴリズムは、外れ値を除外して変換行列を正確に計算します。MSAC アルゴリズムは無作為抽出を利用しているため、変換を計算するたびに異なる結果が生成される場合があります。

[tform,inlierIdx] = estgeotform2d(matchedDistorted,matchedOriginal,"similarity");
inlierDistorted = matchedDistorted(inlierIdx,:);
inlierOriginal = matchedOriginal(inlierIdx,:);

変換の計算で使用されたマッチするポイントのペアを表示します。

figure;
showMatchedFeatures(original,distorted,inlierOriginal,inlierDistorted);
title("Matching points (inliers only)");
legend("ptsOriginal","ptsDistorted");

スケールと角度の解

幾何学的変換 tform を使用して、スケールと角度を復元します。計算された変換は歪んだイメージから元のイメージへの変換であるため、歪みを復元するにはその逆を計算しなければなりません。

Let sc = s*cos(theta)
Let ss = s*sin(theta)
Then, Ainv = [sc  ss  tx;
             -ss  sc  ty;
               0   0   1]
where tx and ty are x and y translations, respectively.

逆変換行列を計算します。

invTform = invert(tform);
Ainv = invTform.A;

ss = Ainv(1,2);
sc = Ainv(1,1);
scaleRecovered = hypot(ss,sc);
disp(["Recovered scale: ",num2str(scaleRecovered)])

% Recover the rotation in which a positive value represents a rotation in
% the clockwise direction.
thetaRecovered = atan2d(-ss,sc);
disp(["Recovered theta: ",num2str(thetaRecovered)])
    "Recovered scale: "    "0.70126"

    "Recovered theta: "    "29.3451"

復元された値は、イメージのサイズ変更と回転の処理時に選択されたスケールおよび角度の値と一致するはずです。また、スケールと回転角度は、simtform2d オブジェクトのスケールおよび回転角度のプロパティで確認できます。

disp(["Scale: " num2str(invTform.Scale)])
disp(["RotationAngle: " num2str(invTform.RotationAngle)])
    "Scale: "    "0.70126"

    "RotationAngle: "    "29.3451"

元のイメージの復元

歪んだイメージを変換して元のイメージを復元します。

outputView = imref2d(size(original));
recovered = imwarp(distorted,tform,OutputView=outputView);

モンタージュで recoveredoriginal を並べて比較します。

figure,imshowpair(original,recovered,"montage")

歪みと復元処理のため、recovered (右) の画質は original (左) の画質と一致していません。特に、イメージを縮小すると情報が失われます。エッジ近辺にアーティファクトがあるのは、変換の精度に制限があるためです。イメージ間で一致する特徴を見つける処理において、より多くのポイントを検出すると変換精度が向上します。たとえば、detectFASTFeatures などのコーナー検出器を組み込むと、ブロブを識別する SURF 特徴検出器を補完できます。また、イメージの内容とサイズも、検出される特徴の数に影響します。