11

LogPolar 変換を使用して、2 つの画像からスケールと回転角度を取得しようとしています。以下は、2 つの 300x300 サンプル画像です。最初の長方形は 100x100 で、2 番目の長方形は 150x150 で、45 度回転しています。

ここに画像の説明を入力 ここに画像の説明を入力

アルゴリズム:

  1. 両方の画像を LogPolar に変換します。
  2. 位相相関を使用して並進シフトを見つけます。
  3. 並進シフトをスケールと回転角度に変換します (これを行う方法は?)。

私のコード:

#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/imgproc/imgproc_c.h>
#include <opencv2/highgui/highgui.hpp>
#include <iostream>

int main()
{
    cv::Mat a = cv::imread("rect1.png", 0);
    cv::Mat b = cv::imread("rect2.png", 0);
    if (a.empty() || b.empty())
        return -1;

    cv::imshow("a", a);
    cv::imshow("b", b);

    cv::Mat pa = cv::Mat::zeros(a.size(), CV_8UC1);
    cv::Mat pb = cv::Mat::zeros(b.size(), CV_8UC1);
    IplImage ipl_a = a, ipl_pa = pa;
    IplImage ipl_b = b, ipl_pb = pb;
    cvLogPolar(&ipl_a, &ipl_pa, cvPoint2D32f(a.cols >> 1, a.rows >> 1), 40);
    cvLogPolar(&ipl_b, &ipl_pb, cvPoint2D32f(b.cols >> 1, b.rows >> 1), 40);

    cv::imshow("logpolar a", pa);
    cv::imshow("logpolar b", pb);

    cv::Mat pa_64f, pb_64f;
    pa.convertTo(pa_64f, CV_64F);
    pb.convertTo(pb_64f, CV_64F);

    cv::Point2d pt = cv::phaseCorrelate(pa_64f, pb_64f);

    std::cout << "Shift = " << pt 
              << "Rotation = " << cv::format("%.2f", pt.y*180/(a.cols >> 1)) 
              << std::endl;

    cv::waitKey(0);

    return 0;
}

対極画像:

ここに画像の説明を入力 ここに画像の説明を入力

上記のサンプル イメージ イメージの場合、並進シフトは(16.2986, 36.9105)です。である回転角度を取得することに成功しました44.29。しかし、私はスケールを計算するのが難しいです。指定された並進シフトを変換してスケールを取得する方法は?

4

5 に答える 5

2

2つの画像f1f2があり、f1(m、n)= f2(m / a、n / a)です。つまり、f1は係数aでスケーリングされます。

f1(log m、log n)= f2(logm − log a、log n − log a)同等の対数表記では、logaは位相相関画像のシフトです。

BS Reddy、BN Chatterjiを比較してください:平行移動、回転、およびスケール不変の画像レジストレーションのためのFFTベースの手法、画像処理に関するIEEEトランザクションVol。5 No. 8、IEEE、1996

http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.185.4387&rep=rep1&type=pdf

于 2013-01-09T22:48:02.903 に答える
2

ここにpythonバージョンがあります

それは言う

ir = abs(ifft2((f0 * f1.conjugate()) / r0))
    i0, i1 = numpy.unravel_index(numpy.argmax(ir), ir.shape)
    angle = 180.0 * i0 / ir.shape[0]
    scale = log_base ** i1
于 2013-04-30T08:13:09.767 に答える
0

位相相関による値から、座標は直角座標であるため、(16.2986, 36.9105) は (x,y) です。スケールは次のように計算されます。

scale = log((x^2 + y^ 2)^0.5) これは約 1.6 (1.5 に近い) です。

式を使用して角度を計算すると、theta = arctan(y/x) = 66(approx) となります。シータ値は、実際の値 (この場合は 45) に近い値です。

于 2013-07-08T06:17:17.700 に答える