SOARISTO工房 Logo

【OpenCV】回転不変位相限定相関法による画像マッチング(1)

 前回までの検証により、

  1. 画像をフーリエ変換し、振幅で正規化した後、逆フーリエ変換すると、位相情報を表す画像(位相画像)を得ることができる。
  2. 2つの画像の位相情報の畳み込み(合成積)を取り、振幅で正規化した後、逆フーリエ変換すると、2つの画像の間のシフト量(X方向, Y方向)を得ることができる。
    (これを、「位相限定相関法」という)
  3. 実座標を対数極座標に変換すると、実座標における回転方向の動きを、対数極座標における縦方向の動きとして表すことができる。

ということが分かりました。

 これらを組み合わせて、2つの画像の間の回転方向のズレ(画像のロール角)を推定してみることにします。

 「回転不変位相限定相関法」(RIPOC; Rotation Invariant Phase Only Correlation Method)です。

 回転不変位相限定相関法の処理手順は、以下のようになります。

OpenCV, RIPOC, Rotation Invariant Phase Only Correlation

 まずは、原画像(1920×1080)から、評価用の画像を作ります。

OpenCV, RIPOC, Rotation Invariant Phase Only Correlation

 青枠のところを切り出し、画像Aとします。さらに、X方向に29.5, Y方向に14.5シフトし、反時計回りに19.0°回転させて赤枠のところで切り出し、画像Bとします。

 2つの画像の間のシフト量およびロール角は、リサイズ後の画素に換算すると、

   X: 19.796[pixel]
   Y: 9.730[pixel]
   θ: 19.0[degree]

となります。

 ここで、「比較される側の画像」を画像A、「比較する側の画像」を画像Bとします。

OpenCV, RIPOC, Rotation Invariant Phase Only Correlation

 2つの画像を離散フーリエ変換(DFT)すると、それぞれ以下のようになります。

OpenCV, RIPOC, Rotation Invariant Phase Only Correlation

 このDFT画像を対数極座標(Log-Polar)に変換すると、それぞれ以下のようになります。

OpenCV, RIPOC, Rotation Invariant Phase Only Correlation

 この2つの画像の間のシフト量を、位相限定相関法により得ます。(Pass1)

 このシフト量(x, y)を、ロール角(θ)とスケール(ρ)に換算し、「比較する側の画像」を補正します。(画像B3)

OpenCV, RIPOC, Rotation Invariant Phase Only Correlation

 さらに、補正した「比較する側の画像」と「比較される側の画像」の間のシフト量を、位相限定相関法により得ます。(Pass2)

 このシフト量(x', y')により、「比較する側の画像」をさらに補正します。(画像B4)

OpenCV, RIPOC, Rotation Invariant Phase Only Correlation

 いががでしょうか。

OpenCV, RIPOC, Rotation Invariant Phase Only Correlation

 実行結果です。

   X: 19.9695[pixel]
   Y: 9.92706[pixel]
   θ: 18.9985[degree]

 怖いくらいピタリと一致しています。その誤差は、以前の検証と同じ、±0.20[pixel]程度です。
(プログラムを書いている自分でも、驚いてしまうくらいです)

 Pass2におけるピーク値(最大値:1.0)は、0.926851となっていることから、「かなり似ているよ」といわれています。

#すばらしい!0xF9CF

〔関連情報〕
   ・【OpenCV】対数極座標画像の生成
   ・【OpenCV】位相限定相関法による画像マッチング(3)
   ・【OpenCV】位相限定相関法による画像マッチング(2)
   ・【OpenCV】位相限定相関法による画像マッチング(1)
   ・【OpenCV】ステレオカメラからの画像入力(1)
   ・【OpenCV】位相画像の生成
   ・【OpenCV】広角レンズの歪み補正

Trackback(0)

Trackback URL: http://www.soaristo.jpn.org/mt/mt-tb.cgi/1005

Comments(10)

初めまして。お聞きしたいことがあり、以下長文になってしまいますがご容赦ください。

最初に私の開発環境を記載しておきます。

【開発環境】
・C++Builder 5
・OpenCV 1.0
(C++Builder 5での開発の為、OpenCVは1.0です)

画像マッチングの記事を参考にさせて頂き、POCでの位置ズレ取得は、おかげさまでなんとか出来ました。(ピーク位置は cvMinMaxLoc で整数で取得しました)
しかし、RIPOC のロール角取得が出来ず困っております。
スペクトル画像、位相画像、Log-Polar変換画像 はファイル保存して確認もしましたので、出来ていると思います。
Log-Polar変換はOpenCV標準関数の cvLogPolar を使用しました。
(サイズ 256×256 スケールパラメータ 40)

しかし、色々テストしても、0 度(2枚のLog-Polar変換画像の位置ズレなし)になってしまいます。

大変申し訳ありませんが、本記事の「手順1」のロール角推定までのプログラムを教えていただけないでしょうか?
何日もここで詰まってしまっており、お力を貸していただけると助かります。よろしくお願いいたします。

以上、長文失礼いたしました。

posted by  Toma at 21:17:17 2015/10/05 | reply

こんにちわ
ホームページとても参考にさせていただいております。
上記コメント者様同様、私も回転0度になってしまい
悩んでいます。

fftを実行後、Log-Polar変換画像も同様に確認しましたので
できているかと思います。
大変恐縮ですが、当方にもご教授いただけると幸いです。
何卒よろしくお願いいたします。

posted by  inusan at 06:50:20 2016/12/30 | reply

初めまして
いつもホームページを参考にさせていただいております。
過去の位相限定相関法の記事を参考に今回のプログラムを再現しております。
しかしながらロール角とスケールの換算を上手く再現することができません。
恐縮ですが、それらについてより詳細にご教授いただくことは叶いませんでしょうか。
何卒よろしくお願いいたします。

posted by  joe at 16:18:46 2017/01/13 | reply

管理人さま

ご丁寧にプログラムを送っていただきありがとうございました。
回転角、スケールの表示も問題なく実行できました。
ただ画像によって意図しないシフト量や回転角度、出力画像が表示されることがあるので、その点においては改善していきたいと考えております。

posted by  joe at 01:37:25 2017/01/17 | reply

はじめまして。
管理人様のRIPOCに関する投稿を参考にさせて頂きながらコードを書いております。
しかしながら、何度コードを書き直しても回転ずれをうまく導出することができません。
そこで、身勝手なお願いとは承知の上ですが、どうかRIPOCのコードをご教示いただけませんでしょうか。

どうぞよろしくお願い申し上げます。

posted by  sasa at 22:51:29 2017/04/22 | reply

はじめまして。
管理人様のRIPOCの説明を参考にコードを組んでいるのですが、
どうしても上手く回転ずれを導出することができません。
恐縮ですが、手法の詳細についてもう少しご教授いただくことは
できませんでしょうか?

身勝手なお願いで大変申し訳ありませんが、よろしくお願いいたします。

posted by  KSK at 15:49:33 2017/07/03 | reply

Post Comment