Merge pull request #9147 from sovrasov:phase_corr_fix

pull/9692/head
Vadim Pisarevsky 7 years ago
commit 3f794cd951
  1. 54
      modules/imgproc/src/phasecorr.cpp
  2. 40
      modules/imgproc/test/test_pc.cpp

@ -372,37 +372,57 @@ static void fftShift(InputOutputArray _out)
if(is_1d)
{
int is_odd = (xMid > 0 && out.cols % 2 == 1) || (yMid > 0 && out.rows % 2 == 1);
xMid = xMid + yMid;
for(size_t i = 0; i < planes.size(); i++)
{
Mat tmp;
Mat half0(planes[i], Rect(0, 0, xMid, 1));
Mat half1(planes[i], Rect(xMid, 0, xMid, 1));
Mat half0(planes[i], Rect(0, 0, xMid + is_odd, 1));
Mat half1(planes[i], Rect(xMid + is_odd, 0, xMid, 1));
half0.copyTo(tmp);
half1.copyTo(half0);
tmp.copyTo(half1);
half1.copyTo(planes[i](Rect(0, 0, xMid, 1)));
tmp.copyTo(planes[i](Rect(xMid, 0, xMid + is_odd, 1)));
}
}
else
{
int isXodd = out.cols % 2 == 1;
int isYodd = out.rows % 2 == 1;
for(size_t i = 0; i < planes.size(); i++)
{
// perform quadrant swaps...
Mat tmp;
Mat q0(planes[i], Rect(0, 0, xMid, yMid));
Mat q1(planes[i], Rect(xMid, 0, xMid, yMid));
Mat q2(planes[i], Rect(0, yMid, xMid, yMid));
Mat q3(planes[i], Rect(xMid, yMid, xMid, yMid));
q0.copyTo(tmp);
q3.copyTo(q0);
tmp.copyTo(q3);
q1.copyTo(tmp);
q2.copyTo(q1);
tmp.copyTo(q2);
Mat q0(planes[i], Rect(0, 0, xMid + isXodd, yMid + isYodd));
Mat q1(planes[i], Rect(xMid + isXodd, 0, xMid, yMid + isYodd));
Mat q2(planes[i], Rect(0, yMid + isYodd, xMid + isXodd, yMid));
Mat q3(planes[i], Rect(xMid + isXodd, yMid + isYodd, xMid, yMid));
if(!(isXodd || isYodd))
{
Mat tmp;
q0.copyTo(tmp);
q3.copyTo(q0);
tmp.copyTo(q3);
q1.copyTo(tmp);
q2.copyTo(q1);
tmp.copyTo(q2);
}
else
{
Mat tmp0, tmp1, tmp2 ,tmp3;
q0.copyTo(tmp0);
q1.copyTo(tmp1);
q2.copyTo(tmp2);
q3.copyTo(tmp3);
tmp0.copyTo(planes[i](Rect(xMid, yMid, xMid + isXodd, yMid + isYodd)));
tmp3.copyTo(planes[i](Rect(0, 0, xMid, yMid)));
tmp1.copyTo(planes[i](Rect(0, yMid, xMid, yMid + isYodd)));
tmp2.copyTo(planes[i](Rect(xMid, 0, xMid + isXodd, yMid)));
}
}
}

@ -78,7 +78,7 @@ void CV_PhaseCorrelatorTest::run( int )
Point2d phaseShift = phaseCorrelate(r1, r2, hann);
// test accuracy should be less than 1 pixel...
if((expectedShiftX - phaseShift.x) >= 1 || (expectedShiftY - phaseShift.y) >= 1)
if(std::abs(expectedShiftX - phaseShift.x) >= 1 || std::abs(expectedShiftY - phaseShift.y) >= 1)
{
ts->set_failed_test_info( cvtest::TS::FAIL_BAD_ACCURACY );
}
@ -86,4 +86,42 @@ void CV_PhaseCorrelatorTest::run( int )
TEST(Imgproc_PhaseCorrelatorTest, accuracy) { CV_PhaseCorrelatorTest test; test.safe_run(); }
TEST(Imgproc_PhaseCorrelatorTest, accuracy_real_img)
{
Mat img = imread(cvtest::TS::ptr()->get_data_path() + "shared/airplane.png", IMREAD_GRAYSCALE);
img.convertTo(img, CV_64FC1);
const int xLen = 129;
const int yLen = 129;
const int xShift = 40;
const int yShift = 14;
Mat roi1 = img(Rect(xShift, yShift, xLen, yLen));
Mat roi2 = img(Rect(0, 0, xLen, yLen));
Mat hann;
createHanningWindow(hann, roi1.size(), CV_64F);
Point2d phaseShift = phaseCorrelate(roi1, roi2, hann);
ASSERT_NEAR(phaseShift.x, (double)xShift, 1.);
ASSERT_NEAR(phaseShift.y, (double)yShift, 1.);
}
TEST(Imgproc_PhaseCorrelatorTest, accuracy_1d_odd_fft) {
Mat r1 = Mat::ones(Size(129, 1), CV_64F)*255; // 129 will be completed to 135 before FFT
Mat r2 = Mat::ones(Size(129, 1), CV_64F)*255;
const int xShift = 10;
for(int i = 6; i < 20; i++)
{
r1.at<double>(i) = 1;
r2.at<double>(i + xShift) = 1;
}
Point2d phaseShift = phaseCorrelate(r1, r2);
ASSERT_NEAR(phaseShift.x, (double)xShift, 1.);
}
}

Loading…
Cancel
Save