Main Content

このページの内容は最新ではありません。最新版の英語を参照するには、ここをクリックします。

自動特徴マッチングを使用したイメージの回転とスケールの検出

この例では、イメージのペアの間に見られる幾何学的変換を自動的に判定する方法を説明します。あるイメージをもう 1 つのイメージと比べて回転とスケールによる歪みが見られる場合に、detectSURFFeatures および estgeotform2d を使用して回転角度と倍率を求めます。その後、歪んだイメージを変換して元のイメージを復元することができます。

手順 1: イメージの読み取り

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

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

手順 2: イメージのサイズ変更と回転

scale = 0.7;
J = imresize(original,scale); % Try varying the scale factor.

theta = 30;
% Note that imrotate rotates images in a counterclockwise direction when
% you specify a positive angle of rotation. To rotate the image clockwise,
% specify a negative theta.
distorted = imrotate(J,-theta); % Try varying the angle, theta.
figure
imshow(distorted)

入力イメージのスケールと回転を変化させて実験できます。ただし、スケールの変更可能な量には制限があり、それを超えると特徴検出器が十分な特徴を検出できなくなります。

手順 3: イメージ間で一致する特徴の検出

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

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

手順 4: 変換の推定

RANSAC アルゴリズムのバリエーションである、統計的にロバストな MSAC (M-estimator SAmple Consensus) アルゴリズムを使用して、マッチするポイントのペアに対応した変換を求めます。これにより、変換行列の計算中に外れ値が削除されます。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');

手順 5: スケールと角度の解

幾何学的変換 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

復元された値は、次で選択したスケールと角度の値に一致しなければなりません。「手順 2: イメージのサイズ変更と回転」。

simtform2d オブジェクトの Scale プロパティと RotationAngle プロパティでスケールと回転角度を求めることもできます。

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

手順 6: 元のイメージの復元

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

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

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

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

歪みと復元処理のため、recovered (右) の画質は original (左) の画質と一致していません。特に、イメージを縮小すると情報が失われます。エッジ近辺にアーティファクトがあるのは、変換の精度に制限があるためです。「手順 3: イメージ間で一致する特徴の検出」でより多くの点を検出していれば、変換はより正確になります。たとえば、コーナー検出器 detectFASTFeatures を使用して、ブロブを検出する SURF 特徴量検出器を補うことができます。また、イメージの内容とサイズも、検出される特徴の数に影響を与えます。