mirror of
https://github.com/opencv/opencv.git
synced 2026-09-11 04:43:22 -05:00
Merge pull request #29850 from lazerg:fix/ipc-float32-cps-underflow
imgproc: guard against zero magnitude in phaseCorrelateIterative
This commit is contained in:
@@ -1,11 +1,13 @@
|
||||
#include "precomp.hpp"
|
||||
#include <cmath>
|
||||
#include <limits>
|
||||
|
||||
namespace {
|
||||
|
||||
template <typename T>
|
||||
void calculateCrossPowerSpectrum(const cv::Mat& dft1, const cv::Mat& dft2, cv::Mat& cps)
|
||||
{
|
||||
const T eps = std::numeric_limits<T>::epsilon(); // prevent div0 problems
|
||||
for (int row = 0; row < dft1.rows; ++row)
|
||||
{
|
||||
auto* cpsp = cps.ptr<cv::Vec<T, 2>>(row);
|
||||
@@ -15,7 +17,7 @@ void calculateCrossPowerSpectrum(const cv::Mat& dft1, const cv::Mat& dft2, cv::M
|
||||
{
|
||||
const T re = dft1p[col][0] * dft2p[col][0] + dft1p[col][1] * dft2p[col][1];
|
||||
const T im = dft1p[col][0] * dft2p[col][1] - dft1p[col][1] * dft2p[col][0];
|
||||
const T mag = std::sqrt(re * re + im * im);
|
||||
const T mag = std::sqrt(re * re + im * im) + eps;
|
||||
cpsp[col][0] = re / mag;
|
||||
cpsp[col][1] = im / mag;
|
||||
}
|
||||
|
||||
@@ -24,6 +24,17 @@ Mat GenerateTestImage(Size size)
|
||||
return image;
|
||||
}
|
||||
|
||||
Mat GenerateGaussianImage(Size size, Point2d center)
|
||||
{
|
||||
Mat image(size, CV_32F);
|
||||
for (int row = 0; row < size.height; ++row)
|
||||
for (int col = 0; col < size.width; ++col)
|
||||
image.at<float>(row, col) = static_cast<float>(std::exp(
|
||||
-((col - center.x) * (col - center.x) + (row - center.y) * (row - center.y)) /
|
||||
32.));
|
||||
return image;
|
||||
}
|
||||
|
||||
void TestPhaseCorrelationIterative(const Size& size, const double maxShift)
|
||||
{
|
||||
const auto iters = std::max(201., maxShift * 10 + 1);
|
||||
@@ -114,4 +125,17 @@ TEST(Imgproc_PhaseCorrelationIterative, accuracy_real_img)
|
||||
ASSERT_NEAR(ipcShift.y, (double)yShift, 1.);
|
||||
}
|
||||
|
||||
TEST(Imgproc_PhaseCorrelationIterative, accuracy_32f_smooth_img)
|
||||
{
|
||||
const Point2d center(30., 28.);
|
||||
const Point2d shift(-3., 2.);
|
||||
const Mat image1 = GenerateGaussianImage(Size(64, 64), center);
|
||||
const Mat image2 = GenerateGaussianImage(Size(64, 64), center + shift);
|
||||
|
||||
const Point2d ipcShift = phaseCorrelateIterative(image1, image2);
|
||||
|
||||
ASSERT_NEAR(ipcShift.x, shift.x, 1.);
|
||||
ASSERT_NEAR(ipcShift.y, shift.y, 1.);
|
||||
}
|
||||
|
||||
}} // namespace opencv_test
|
||||
|
||||
Reference in New Issue
Block a user