iOSでPOCに挑戦(5) 二枚の画像を比較する
頭と尻尾はくれてやる! iOSでPOCに挑戦(4) フーリエ変換する
の続きだよ。
フレームワークを使ってiOSでフーリエ変換ができたわけだけど、ここでPOC(位相限定相関法)の式を確認しよう。
解説論文 位相限定相関法に基づく高精度マシンビジョン
↑ここに詳しい計算式の説明があるね。

↑二つの画像をフーリエ変換してその複素共役(complex conjugate)を使って"正規化相互パワースペクトル"を求める、、、へー、そういう名前だったの、と今頃思ってたりするんだけどね。
複素共役を使ってうんぬんする関数がvDSP(Accelerate.framework)にあるからそれを使えば楽チン。
さらにフーリエ逆変換すれば位相限定相関関数(POC関数)を得ることができる、、、へー、そういう名前(以下略)
それじゃあ実際に上の流れで二つの画像を比較してみよう。ここでは一枚の画像から位置をずらして切り出して作るよ。

↑こんな画像を用意してみたよ。サイズはどちらも256x256px。一枚の画像から位置をずらして切り出してる。

↑2枚の画像はx方向が10px、y方向が20pxずらしてるよ。位置が違うだけで、倍率は同じ、角度の変化もなし。
画像をフーリエ変換するのはすでにやってるからいいよね。フーリエ変換した結果はDSPSplitComplexって構造体に入れてたけど、今回は画像が二つあるのでそれぞれsplitComplex1とsplitComplex2ってことで。
POCのためのコードはこんな感じに。

↑結果はこんなの。
一番上は位置をずらした画像、
その次の白黒は輝度を拾って配列に入れて(確認のため)それを画像にして表示したもの、
その次はフーリエ変換した結果の画像、ただし四隅が低周波になってる、
一番下の大きい画像はPOCの結果なんだ。逆フーリエ変換した後にsplitComplex1.realpに入ってるデータを0から255になるよう正規化してから表示させてる。ほら、(10,20)あたりにぽつんと白い点があるでしょ?これがPOCの結果なんだ、ディスプレイのほこりじゃないよ!
今回のように元の画像から位置をずらして二枚の画像を作成したような場合だとこれくらいくっきり結果が出るんだよ。すごいねえ!
今回は平行移動の量を求めただけだけど、FFTした画像をLog-Polar変換してPOCすれば二枚の画像の回転角度、スケールの違いも得ることができる。
頭と尻尾はくれてやる! iOSでPOCに挑戦(1) 位相限定相関法をやってみる
↑この記事にある動画はそうやって角度なども求めてるよ。
ということでだらだらと「iOSでPOCに挑戦」シリーズを書いてきたけど、今回でおしまい!
の続きだよ。
フレームワークを使ってiOSでフーリエ変換ができたわけだけど、ここでPOC(位相限定相関法)の式を確認しよう。
解説論文 位相限定相関法に基づく高精度マシンビジョン
↑ここに詳しい計算式の説明があるね。

↑二つの画像をフーリエ変換してその複素共役(complex conjugate)を使って"正規化相互パワースペクトル"を求める、、、へー、そういう名前だったの、と今頃思ってたりするんだけどね。
複素共役を使ってうんぬんする関数がvDSP(Accelerate.framework)にあるからそれを使えば楽チン。
さらにフーリエ逆変換すれば位相限定相関関数(POC関数)を得ることができる、、、へー、そういう名前(以下略)
それじゃあ実際に上の流れで二つの画像を比較してみよう。ここでは一枚の画像から位置をずらして切り出して作るよ。


↑こんな画像を用意してみたよ。サイズはどちらも256x256px。一枚の画像から位置をずらして切り出してる。

↑2枚の画像はx方向が10px、y方向が20pxずらしてるよ。位置が違うだけで、倍率は同じ、角度の変化もなし。
画像をフーリエ変換するのはすでにやってるからいいよね。フーリエ変換した結果はDSPSplitComplexって構造体に入れてたけど、今回は画像が二つあるのでそれぞれsplitComplex1とsplitComplex2ってことで。
POCのためのコードはこんな感じに。
{ int nData = 256*256; float *array = calloc(nData, sizeof(float));//作業用メモリ確保 //POC処理 vDSP_zvcmul(&splitComplex1,1 , &splitComplex2,1 , &splitComplex1,1 , nData);//---(1) 1の複素共役と2の積 vDSP_zvabs(&splitComplex1,1,array,1,nData);//(1)のsqrt(re*re+im*im) を計算---(2) vDSP_zrvdiv(&splitComplex1,1,array,1,&splitComplex1,1,nData);//---(1)/(2)をsplitComplex1に入れる //逆FFT vDSP_fft2d_zip(fftSetup,&splitComplex1,1,0,8,8,FFT_INVERSE);//2^8=256 }たったこれだけだよ。

↑結果はこんなの。
一番上は位置をずらした画像、
その次の白黒は輝度を拾って配列に入れて(確認のため)それを画像にして表示したもの、
その次はフーリエ変換した結果の画像、ただし四隅が低周波になってる、
一番下の大きい画像はPOCの結果なんだ。逆フーリエ変換した後にsplitComplex1.realpに入ってるデータを0から255になるよう正規化してから表示させてる。ほら、(10,20)あたりにぽつんと白い点があるでしょ?これがPOCの結果なんだ、ディスプレイのほこりじゃないよ!
今回のように元の画像から位置をずらして二枚の画像を作成したような場合だとこれくらいくっきり結果が出るんだよ。すごいねえ!
今回は平行移動の量を求めただけだけど、FFTした画像をLog-Polar変換してPOCすれば二枚の画像の回転角度、スケールの違いも得ることができる。
頭と尻尾はくれてやる! iOSでPOCに挑戦(1) 位相限定相関法をやってみる
↑この記事にある動画はそうやって角度なども求めてるよ。
ということでだらだらと「iOSでPOCに挑戦」シリーズを書いてきたけど、今回でおしまい!
スポンサーサイト
<< Googleドライブの容量をアップグレードした TopPage iOSでPOCに挑戦(4) フーリエ変換する >>
トラックバック
トラックバックURL
https://ringsbell.blog.fc2.com/tb.php/739-547c5b6f
https://ringsbell.blog.fc2.com/tb.php/739-547c5b6f