Archive
一生懸命POCを実装していましたが、
OpenCV内にphaseCorrelateとしてPOCが定義されているのを発見しました。

ヘルプなどあさってみましたが特に記載されていないため、
まだベータ版なのかもしれませんが問題なく動作していたためご紹介を

opencvフォルダ内の以下のディレクトリにそれぞれ格納されていました。
関数自体の定義
modules\imgproc\src\phasecorr.cpp
モジュール(?)のテスト
modules\imgproc\test\test_pc.cpp
使用方法
samples\cpp\phase_corr.cpp



ソース

phase_corr.cppをそのまま転載します。

#include "opencv2/core/core.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"

using namespace cv;

int main(int, char* [])
{
    VideoCapture video(0);
    Mat frame, curr, prev, curr64f, prev64f, hann;
    int key = 0;

    do
    {
        video >> frame;
        cvtColor(frame, curr, CV_RGB2GRAY);

        if(prev.empty())
        {
            prev = curr.clone();
            createHanningWindow(hann, curr.size(), CV_64F);
        }

        prev.convertTo(prev64f, CV_64F);
        curr.convertTo(curr64f, CV_64F);

        Point2d shift = phaseCorrelate(prev64f, curr64f, hann);
        double radius = cv::sqrt(shift.x*shift.x + shift.y*shift.y);

        if(radius > 5)
        {
            // draw a circle and line indicating the shift direction...
            Point center(curr.cols >> 1, curr.rows >> 1);
            cv::circle(frame, center, (int)radius, cv::Scalar(0, 255, 0), 3, CV_AA);
            cv::line(frame, center, Point(center.x + (int)shift.x, center.y + (int)shift.y), cv::Scalar(0, 255, 0), 3, CV_AA);
        }

        imshow("phase shift", frame);
        key = waitKey(2);

        prev = curr.clone();
    } while((char)key != 27); // Esc to exit...

    return 0;
}



27行目がPOCです。画像を渡すとPoint2dで座標が返却されます。
動作内容はカメラから画像(フレーム)を取得し、前のフレームと比較しカメラがどちらに動いているか判定するようです。
移動方向をフレーム中心の円の大きさを用いて表示するようになっております。

参考までにご紹介です。
OpenCVSharpの公式サイトに記載されているので、ご存じかもしれませんが。
< デバッグ中にIplImageの中を確認する方法をメモしておきます。

DebuggerVisualizer - opencvsharp http://code.google.com/p/opencvsharp/wiki/DebuggerVisualizer

導入方法

OpenCVSharpの中に含まれているdllの中に

OpenCvSharp.DebuggerVisualizers.dll

があります。
それを、My DocumentのVisual StudioのVisualizersというフォルダにコピーします。

VistaでVisual Studio2010の例ですと。
C:\Users\XXX\Documents\Visual Studio 2010\Visualizers
になります。


使い方

デバッグ中にIplImageの変数にフォーカスを当てると、虫メガネのマークが表示されるので
それをクリックすると現在の状況の画像が表示されます。

Log-Polar変換なのですが、霊長類の網膜のモデルらしいです。
中心部は解像度が高いのですが、周辺部は低いという特性らしいです。

以下のような式で変換をします。(極座標変換でのrにlogをとったものです。)
logpolar.png


ですが、今まで行った回転のときのように、どの変換先の座標は元画像のどの位置を参照するかと考えます。
すなわち以下の逆変換を使います。
logpolar2.png



ソース


OpenCVのやりかたを真似したため、一部のみ抜粋です。
bmpが入力画像、lpcが出力画像です。
また、Mはformから入力された値を使用しました。256x256だと40くらいがよさそうです。
BiLinearInterpolationは以前の補間のさいに使用したものです。

画像を回転させる際の画素を補間するコード | 詠み人知らずの備忘録


Bitmap lpc = new Bitmap(bmp.Width, bmp.Height);

int cx = lpc.Width / 2;
int cy = lpc.Height / 2;

double M = Convert.ToDouble(textBox1.Text);

for (int i = 0; i < lpc.Width; i++)
{
    for (int j = 0; j < lpc.Height; j++)
    {
        double r = Math.Exp((double)i / (double)M);
        double x = r * Math.Cos(2 * Math.PI * j / lpc.Height) + cx;
        double y = r * Math.Sin(2 * Math.PI * j / lpc.Height) + cy;
        
        if (0 < x && x < bmp.Width - 1 && 0 < y && y < bmp.Height - 1)
        {
            Color bmpCol = BiLinearInterpolation(x, y, bmp);
            lpc.SetPixel(i, j, bmpCol);
        }

    }
}



結果

変換した結果、(x,y)と(rho,phi)の関係がどのような対応になるのかは、下記のサイトがイメージがつきやすいと思います。
Log polar transform - Rhea



※クリックで拡大します。

【元画像】
Lenna

【変換画像】
Lenna_log.png

【元画像】
Lenna_90.png

【変換画像】
Lenna_log90.png



画像の回転が、変換後の画像の下への移動としてあらわされています。
この考え方を、位相限定相関法(POC)と供に使用すると、角度のズレを判別できるためより便利な手法となります。(RIPOCという手法らしいです。)

位相限定相関法(POC) - スズメレンダラー・クマ将棋の開発日記

FC2カウンター
プロフィール

詠み人知らず

Author:詠み人知らず
プログラム好きな名もなき凡人がお送りしています。(得意とは言っていない
最近の興味はPython、C#、Matlab(Octave)、画像処理、AR(拡張現実)、統計などなど・・・

気分で思いついたことを書くため話題に一貫性がないかもしれません。

カレンダー
01 | 2013/02 | 03
- - - - - 1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 - -
最新記事
タグクラウドとサーチ

カテゴリ
最新コメント
最新トラックバック
月別アーカイブ