mirror of
https://github.com/opencv/opencv.git
synced 2025-08-06 06:26:29 +08:00
Updated warpAffine test to ensure bit-exactness for CV_8U (#10921)
* Updated warpAffine test to ensure bit-exactness for CV_8U * Updated invertAffineTransform to bit-exact evaluation
This commit is contained in:
parent
62cf71002e
commit
c80a168d9d
@ -52,6 +52,7 @@
|
|||||||
#include "hal_replacement.hpp"
|
#include "hal_replacement.hpp"
|
||||||
|
|
||||||
#include "opencv2/core/openvx/ovx_defs.hpp"
|
#include "opencv2/core/openvx/ovx_defs.hpp"
|
||||||
|
#include "opencv2/core/softfloat.hpp"
|
||||||
#include "imgwarp.hpp"
|
#include "imgwarp.hpp"
|
||||||
|
|
||||||
using namespace cv;
|
using namespace cv;
|
||||||
@ -172,7 +173,7 @@ static inline void interpolateLanczos4( float x, float* coeffs )
|
|||||||
}
|
}
|
||||||
|
|
||||||
float sum = 0;
|
float sum = 0;
|
||||||
double y0=-(x+3)*CV_PI*0.25, s0 = sin(y0), c0=cos(y0);
|
double y0=-(x+3)*CV_PI*0.25, s0 = std::sin(y0), c0= std::cos(y0);
|
||||||
for(int i = 0; i < 8; i++ )
|
for(int i = 0; i < 8; i++ )
|
||||||
{
|
{
|
||||||
double y = -(x+3-i)*CV_PI*0.25;
|
double y = -(x+3-i)*CV_PI*0.25;
|
||||||
@ -3079,8 +3080,8 @@ cv::Mat cv::getRotationMatrix2D( Point2f center, double angle, double scale )
|
|||||||
CV_INSTRUMENT_REGION()
|
CV_INSTRUMENT_REGION()
|
||||||
|
|
||||||
angle *= CV_PI/180;
|
angle *= CV_PI/180;
|
||||||
double alpha = cos(angle)*scale;
|
double alpha = std::cos(angle)*scale;
|
||||||
double beta = sin(angle)*scale;
|
double beta = std::sin(angle)*scale;
|
||||||
|
|
||||||
Mat M(2, 3, CV_64F);
|
Mat M(2, 3, CV_64F);
|
||||||
double* m = M.ptr<double>();
|
double* m = M.ptr<double>();
|
||||||
@ -3199,30 +3200,30 @@ void cv::invertAffineTransform(InputArray _matM, OutputArray __iM)
|
|||||||
|
|
||||||
if( matM.type() == CV_32F )
|
if( matM.type() == CV_32F )
|
||||||
{
|
{
|
||||||
const float* M = matM.ptr<float>();
|
const softfloat* M = matM.ptr<softfloat>();
|
||||||
float* iM = _iM.ptr<float>();
|
softfloat* iM = _iM.ptr<softfloat>();
|
||||||
int step = (int)(matM.step/sizeof(M[0])), istep = (int)(_iM.step/sizeof(iM[0]));
|
int step = (int)(matM.step/sizeof(M[0])), istep = (int)(_iM.step/sizeof(iM[0]));
|
||||||
|
|
||||||
double D = M[0]*M[step+1] - M[1]*M[step];
|
softdouble D = M[0]*M[step+1] - M[1]*M[step];
|
||||||
D = D != 0 ? 1./D : 0;
|
D = D != 0. ? softdouble(1.)/D : softdouble(0.);
|
||||||
double A11 = M[step+1]*D, A22 = M[0]*D, A12 = -M[1]*D, A21 = -M[step]*D;
|
softdouble A11 = M[step+1]*D, A22 = M[0]*D, A12 = -M[1]*D, A21 = -M[step]*D;
|
||||||
double b1 = -A11*M[2] - A12*M[step+2];
|
softdouble b1 = -A11*M[2] - A12*M[step+2];
|
||||||
double b2 = -A21*M[2] - A22*M[step+2];
|
softdouble b2 = -A21*M[2] - A22*M[step+2];
|
||||||
|
|
||||||
iM[0] = (float)A11; iM[1] = (float)A12; iM[2] = (float)b1;
|
iM[0] = A11; iM[1] = A12; iM[2] = b1;
|
||||||
iM[istep] = (float)A21; iM[istep+1] = (float)A22; iM[istep+2] = (float)b2;
|
iM[istep] = A21; iM[istep+1] = A22; iM[istep+2] = b2;
|
||||||
}
|
}
|
||||||
else if( matM.type() == CV_64F )
|
else if( matM.type() == CV_64F )
|
||||||
{
|
{
|
||||||
const double* M = matM.ptr<double>();
|
const softdouble* M = matM.ptr<softdouble>();
|
||||||
double* iM = _iM.ptr<double>();
|
softdouble* iM = _iM.ptr<softdouble>();
|
||||||
int step = (int)(matM.step/sizeof(M[0])), istep = (int)(_iM.step/sizeof(iM[0]));
|
int step = (int)(matM.step/sizeof(M[0])), istep = (int)(_iM.step/sizeof(iM[0]));
|
||||||
|
|
||||||
double D = M[0]*M[step+1] - M[1]*M[step];
|
softdouble D = M[0]*M[step+1] - M[1]*M[step];
|
||||||
D = D != 0 ? 1./D : 0;
|
D = D != 0. ? softdouble(1.)/D : softdouble(0.);
|
||||||
double A11 = M[step+1]*D, A22 = M[0]*D, A12 = -M[1]*D, A21 = -M[step]*D;
|
softdouble A11 = M[step+1]*D, A22 = M[0]*D, A12 = -M[1]*D, A21 = -M[step]*D;
|
||||||
double b1 = -A11*M[2] - A12*M[step+2];
|
softdouble b1 = -A11*M[2] - A12*M[step+2];
|
||||||
double b2 = -A21*M[2] - A22*M[step+2];
|
softdouble b2 = -A21*M[2] - A22*M[step+2];
|
||||||
|
|
||||||
iM[0] = A11; iM[1] = A12; iM[2] = b1;
|
iM[0] = A11; iM[1] = A12; iM[2] = b1;
|
||||||
iM[istep] = A21; iM[istep+1] = A22; iM[istep+2] = b2;
|
iM[istep] = A21; iM[istep+1] = A22; iM[istep+2] = b2;
|
||||||
@ -3497,8 +3498,8 @@ void cv::logPolar( InputArray _src, OutputArray _dst,
|
|||||||
|
|
||||||
for (phi = 0; phi < dsize.height; phi++)
|
for (phi = 0; phi < dsize.height; phi++)
|
||||||
{
|
{
|
||||||
double cp = cos(phi * 2 * CV_PI / dsize.height);
|
double cp = std::cos(phi * 2 * CV_PI / dsize.height);
|
||||||
double sp = sin(phi * 2 * CV_PI / dsize.height);
|
double sp = std::sin(phi * 2 * CV_PI / dsize.height);
|
||||||
float* mx = (float*)(mapx.data + phi*mapx.step);
|
float* mx = (float*)(mapx.data + phi*mapx.step);
|
||||||
float* my = (float*)(mapy.data + phi*mapy.step);
|
float* my = (float*)(mapy.data + phi*mapy.step);
|
||||||
|
|
||||||
@ -3699,8 +3700,8 @@ void cv::linearPolar( InputArray _src, OutputArray _dst,
|
|||||||
|
|
||||||
for (phi = 0; phi < dsize.height; phi++)
|
for (phi = 0; phi < dsize.height; phi++)
|
||||||
{
|
{
|
||||||
double cp = cos(phi * 2 * CV_PI / dsize.height);
|
double cp = std::cos(phi * 2 * CV_PI / dsize.height);
|
||||||
double sp = sin(phi * 2 * CV_PI / dsize.height);
|
double sp = std::sin(phi * 2 * CV_PI / dsize.height);
|
||||||
float* mx = (float*)(mapx.data + phi*mapx.step);
|
float* mx = (float*)(mapx.data + phi*mapx.step);
|
||||||
float* my = (float*)(mapy.data + phi*mapy.step);
|
float* my = (float*)(mapy.data + phi*mapy.step);
|
||||||
|
|
||||||
|
@ -77,6 +77,7 @@ protected:
|
|||||||
|
|
||||||
virtual void run_func() = 0;
|
virtual void run_func() = 0;
|
||||||
virtual void run_reference_func() = 0;
|
virtual void run_reference_func() = 0;
|
||||||
|
virtual float get_success_error_level(int _interpolation, int _depth) const;
|
||||||
virtual void validate_results() const;
|
virtual void validate_results() const;
|
||||||
virtual void prepare_test_data_for_reference_func();
|
virtual void prepare_test_data_for_reference_func();
|
||||||
|
|
||||||
@ -229,6 +230,20 @@ void CV_ImageWarpBaseTest::run(int)
|
|||||||
ts->set_gtest_status();
|
ts->set_gtest_status();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float CV_ImageWarpBaseTest::get_success_error_level(int _interpolation, int) const
|
||||||
|
{
|
||||||
|
if (_interpolation == INTER_CUBIC)
|
||||||
|
return 1.0f;
|
||||||
|
else if (_interpolation == INTER_LANCZOS4)
|
||||||
|
return 1.0f;
|
||||||
|
else if (_interpolation == INTER_NEAREST)
|
||||||
|
return 1.0f;
|
||||||
|
else if (_interpolation == INTER_AREA)
|
||||||
|
return 2.0f;
|
||||||
|
else
|
||||||
|
return 1.0f;
|
||||||
|
}
|
||||||
|
|
||||||
void CV_ImageWarpBaseTest::validate_results() const
|
void CV_ImageWarpBaseTest::validate_results() const
|
||||||
{
|
{
|
||||||
Mat _dst;
|
Mat _dst;
|
||||||
@ -237,15 +252,7 @@ void CV_ImageWarpBaseTest::validate_results() const
|
|||||||
Size dsize = dst.size(), ssize = src.size();
|
Size dsize = dst.size(), ssize = src.size();
|
||||||
int cn = _dst.channels();
|
int cn = _dst.channels();
|
||||||
dsize.width *= cn;
|
dsize.width *= cn;
|
||||||
float t = 1.0f;
|
float t = get_success_error_level(interpolation & INTER_MAX, dst.depth());
|
||||||
if (interpolation == INTER_CUBIC)
|
|
||||||
t = 1.0f;
|
|
||||||
else if (interpolation == INTER_LANCZOS4)
|
|
||||||
t = 1.0f;
|
|
||||||
else if (interpolation == INTER_NEAREST)
|
|
||||||
t = 1.0f;
|
|
||||||
else if (interpolation == INTER_AREA)
|
|
||||||
t = 2.0f;
|
|
||||||
|
|
||||||
for (int dy = 0; dy < dsize.height; ++dy)
|
for (int dy = 0; dy < dsize.height; ++dy)
|
||||||
{
|
{
|
||||||
@ -1034,7 +1041,7 @@ public:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void generate_test_data();
|
virtual void generate_test_data();
|
||||||
virtual void prepare_test_data_for_reference_func();
|
virtual float get_success_error_level(int _interpolation, int _depth) const;
|
||||||
|
|
||||||
virtual void run_func();
|
virtual void run_func();
|
||||||
virtual void run_reference_func();
|
virtual void run_reference_func();
|
||||||
@ -1083,16 +1090,16 @@ void CV_WarpAffine_Test::run_func()
|
|||||||
cv::warpAffine(src, dst, M, dst.size(), interpolation, borderType, borderValue);
|
cv::warpAffine(src, dst, M, dst.size(), interpolation, borderType, borderValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CV_WarpAffine_Test::prepare_test_data_for_reference_func()
|
float CV_WarpAffine_Test::get_success_error_level(int _interpolation, int _depth) const
|
||||||
{
|
{
|
||||||
CV_ImageWarpBaseTest::prepare_test_data_for_reference_func();
|
return _depth == CV_8U ? 0 : CV_ImageWarpBaseTest::get_success_error_level(_interpolation, _depth);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CV_WarpAffine_Test::run_reference_func()
|
void CV_WarpAffine_Test::run_reference_func()
|
||||||
{
|
{
|
||||||
prepare_test_data_for_reference_func();
|
Mat tmp = Mat::zeros(dst.size(), dst.type());
|
||||||
|
warpAffine(src, tmp);
|
||||||
warpAffine(src, reference_dst);
|
tmp.convertTo(reference_dst, reference_dst.depth());
|
||||||
}
|
}
|
||||||
|
|
||||||
void CV_WarpAffine_Test::warpAffine(const Mat& _src, Mat& _dst)
|
void CV_WarpAffine_Test::warpAffine(const Mat& _src, Mat& _dst)
|
||||||
@ -1123,7 +1130,7 @@ void CV_WarpAffine_Test::warpAffine(const Mat& _src, Mat& _dst)
|
|||||||
const int AB_SCALE = 1 << AB_BITS;
|
const int AB_SCALE = 1 << AB_BITS;
|
||||||
int round_delta = (inter == INTER_NEAREST) ? AB_SCALE / 2 : (AB_SCALE / INTER_TAB_SIZE / 2);
|
int round_delta = (inter == INTER_NEAREST) ? AB_SCALE / 2 : (AB_SCALE / INTER_TAB_SIZE / 2);
|
||||||
|
|
||||||
const double* data_tM = tM.ptr<double>(0);
|
const softdouble* data_tM = tM.ptr<softdouble>(0);
|
||||||
for (int dy = 0; dy < dsize.height; ++dy)
|
for (int dy = 0; dy < dsize.height; ++dy)
|
||||||
{
|
{
|
||||||
short* yM = mapx.ptr<short>(dy);
|
short* yM = mapx.ptr<short>(dy);
|
||||||
@ -1162,6 +1169,7 @@ public:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void generate_test_data();
|
virtual void generate_test_data();
|
||||||
|
virtual float get_success_error_level(int _interpolation, int _depth) const;
|
||||||
|
|
||||||
virtual void run_func();
|
virtual void run_func();
|
||||||
virtual void run_reference_func();
|
virtual void run_reference_func();
|
||||||
@ -1204,11 +1212,16 @@ void CV_WarpPerspective_Test::run_func()
|
|||||||
cv::warpPerspective(src, dst, M, dst.size(), interpolation, borderType, borderValue);
|
cv::warpPerspective(src, dst, M, dst.size(), interpolation, borderType, borderValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float CV_WarpPerspective_Test::get_success_error_level(int _interpolation, int _depth) const
|
||||||
|
{
|
||||||
|
return CV_ImageWarpBaseTest::get_success_error_level(_interpolation, _depth);
|
||||||
|
}
|
||||||
|
|
||||||
void CV_WarpPerspective_Test::run_reference_func()
|
void CV_WarpPerspective_Test::run_reference_func()
|
||||||
{
|
{
|
||||||
prepare_test_data_for_reference_func();
|
Mat tmp = Mat::zeros(dst.size(), dst.type());
|
||||||
|
warpPerspective(src, tmp);
|
||||||
warpPerspective(src, reference_dst);
|
tmp.convertTo(reference_dst, reference_dst.depth());
|
||||||
}
|
}
|
||||||
|
|
||||||
void CV_WarpPerspective_Test::warpPerspective(const Mat& _src, Mat& _dst)
|
void CV_WarpPerspective_Test::warpPerspective(const Mat& _src, Mat& _dst)
|
||||||
|
Loading…
Reference in New Issue
Block a user