diff --git a/modules/imgproc/src/phasecorr.cpp b/modules/imgproc/src/phasecorr.cpp index 0b02a1ec1e..6e9edfad61 100644 --- a/modules/imgproc/src/phasecorr.cpp +++ b/modules/imgproc/src/phasecorr.cpp @@ -372,17 +372,18 @@ 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 diff --git a/modules/imgproc/test/test_pc.cpp b/modules/imgproc/test/test_pc.cpp index f1c86d5757..ce876ba88a 100644 --- a/modules/imgproc/test/test_pc.cpp +++ b/modules/imgproc/test/test_pc.cpp @@ -86,4 +86,21 @@ void CV_PhaseCorrelatorTest::run( int ) TEST(Imgproc_PhaseCorrelatorTest, accuracy) { CV_PhaseCorrelatorTest test; test.safe_run(); } +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(i) = 1; + r2.at(i + xShift) = 1; + } + + Point2d phaseShift = phaseCorrelate(r1, r2); + + ASSERT_NEAR(phaseShift.x, (double)xShift, .5); +} + }