mirror of
https://github.com/opencv/opencv.git
synced 2026-07-30 07:43:03 +04:00
Merge pull request #25671 from savuor:rv/arithm_extend_tests
Tests added for mixed type arithmetic operations #25671 ### Changes * added accuracy tests for mixed type arithmetic operations _Note: div-by-zero values are removed from checking since the result is implementation-defined in common case_ * added perf tests for the same cases * fixed a typo in `getMulExtTab()` function that lead to dead code ### Pull Request Readiness Checklist See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request - [x] I agree to contribute to the project under Apache 2 License. - [x] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV - [x] The PR is proposed to the proper branch - [x] There is a reference to the original bug report and related work - [x] There is accuracy test, performance test and test data in opencv_extra repository, if applicable Patch to opencv_extra has the same branch name. - [x] The feature is well documented and sample code can be built with the project CMake
This commit is contained in:
committed by
GitHub
parent
1bd5ca1ebe
commit
a7e53aa184
+69
-42
@@ -2551,30 +2551,31 @@ void max(const Mat& src1, double val, Mat& dst)
|
||||
}
|
||||
|
||||
|
||||
template<typename _Tp> static void
|
||||
muldiv_(const _Tp* src1, const _Tp* src2, _Tp* dst, size_t total, double scale, char op)
|
||||
template<typename SrcType, typename DstType> static void
|
||||
muldiv_(const SrcType* src1, const SrcType* src2, DstType* dst, size_t total, double scale, char op)
|
||||
{
|
||||
if( op == '*' )
|
||||
for( size_t i = 0; i < total; i++ )
|
||||
dst[i] = saturate_cast<_Tp>((scale*src1[i])*src2[i]);
|
||||
else if( src1 )
|
||||
for( size_t i = 0; i < total; i++ )
|
||||
dst[i] = src2[i] ? saturate_cast<_Tp>((scale*src1[i])/src2[i]) : 0;
|
||||
else
|
||||
for( size_t i = 0; i < total; i++ )
|
||||
dst[i] = src2[i] ? saturate_cast<_Tp>(scale/src2[i]) : 0;
|
||||
for( size_t i = 0; i < total; i++ )
|
||||
{
|
||||
double m1 = src1 ? (double)src1[i] : 1.0;
|
||||
double m2 = src2 ? (double)src2[i] : 1.0;
|
||||
if (op == '/')
|
||||
{
|
||||
m2 = abs(m2) > FLT_EPSILON ? (1.0 / m2) : 0;
|
||||
}
|
||||
dst[i] = saturate_cast<DstType>(scale * m1 * m2);
|
||||
}
|
||||
}
|
||||
|
||||
static void muldiv(const Mat& src1, const Mat& src2, Mat& dst, double scale, char op)
|
||||
static void muldiv(const Mat& src1, const Mat& src2, Mat& dst, int ctype, double scale, char op)
|
||||
{
|
||||
dst.create(src2.dims, src2.size, src2.type());
|
||||
dst.create(src2.dims, src2.size, (ctype >= 0 ? ctype : src2.type()));
|
||||
CV_Assert( src1.empty() || (src1.type() == src2.type() && src1.size == src2.size) );
|
||||
const Mat *arrays[]={&src1, &src2, &dst, 0};
|
||||
Mat planes[3];
|
||||
|
||||
NAryMatIterator it(arrays, planes);
|
||||
size_t total = planes[1].total()*planes[1].channels();
|
||||
size_t i, nplanes = it.nplanes, depth = src2.depth();
|
||||
size_t i, nplanes = it.nplanes, srcDepth = src2.depth(), dstDepth = dst.depth();
|
||||
|
||||
for( i = 0; i < nplanes; i++, ++it )
|
||||
{
|
||||
@@ -2582,44 +2583,70 @@ static void muldiv(const Mat& src1, const Mat& src2, Mat& dst, double scale, cha
|
||||
const uchar* sptr2 = planes[1].ptr();
|
||||
uchar* dptr = planes[2].ptr();
|
||||
|
||||
switch( depth )
|
||||
if (srcDepth == dstDepth)
|
||||
{
|
||||
case CV_8U:
|
||||
muldiv_((const uchar*)sptr1, (const uchar*)sptr2, (uchar*)dptr, total, scale, op);
|
||||
break;
|
||||
case CV_8S:
|
||||
muldiv_((const schar*)sptr1, (const schar*)sptr2, (schar*)dptr, total, scale, op);
|
||||
break;
|
||||
case CV_16U:
|
||||
muldiv_((const ushort*)sptr1, (const ushort*)sptr2, (ushort*)dptr, total, scale, op);
|
||||
break;
|
||||
case CV_16S:
|
||||
muldiv_((const short*)sptr1, (const short*)sptr2, (short*)dptr, total, scale, op);
|
||||
break;
|
||||
case CV_32S:
|
||||
muldiv_((const int*)sptr1, (const int*)sptr2, (int*)dptr, total, scale, op);
|
||||
break;
|
||||
case CV_32F:
|
||||
muldiv_((const float*)sptr1, (const float*)sptr2, (float*)dptr, total, scale, op);
|
||||
break;
|
||||
case CV_64F:
|
||||
muldiv_((const double*)sptr1, (const double*)sptr2, (double*)dptr, total, scale, op);
|
||||
break;
|
||||
default:
|
||||
CV_Error(Error::StsUnsupportedFormat, "");
|
||||
switch( srcDepth )
|
||||
{
|
||||
case CV_8U:
|
||||
muldiv_((const uchar*)sptr1, (const uchar*)sptr2, (uchar*)dptr, total, scale, op);
|
||||
break;
|
||||
case CV_8S:
|
||||
muldiv_((const schar*)sptr1, (const schar*)sptr2, (schar*)dptr, total, scale, op);
|
||||
break;
|
||||
case CV_16U:
|
||||
muldiv_((const ushort*)sptr1, (const ushort*)sptr2, (ushort*)dptr, total, scale, op);
|
||||
break;
|
||||
case CV_16S:
|
||||
muldiv_((const short*)sptr1, (const short*)sptr2, (short*)dptr, total, scale, op);
|
||||
break;
|
||||
case CV_32S:
|
||||
muldiv_((const int*)sptr1, (const int*)sptr2, (int*)dptr, total, scale, op);
|
||||
break;
|
||||
case CV_32F:
|
||||
muldiv_((const float*)sptr1, (const float*)sptr2, (float*)dptr, total, scale, op);
|
||||
break;
|
||||
case CV_64F:
|
||||
muldiv_((const double*)sptr1, (const double*)sptr2, (double*)dptr, total, scale, op);
|
||||
break;
|
||||
default:
|
||||
CV_Error(Error::StsUnsupportedFormat, "");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (srcDepth == CV_8U && dstDepth == CV_16U)
|
||||
{
|
||||
muldiv_((const uchar*)sptr1, (const uchar*)sptr2, (ushort*)dptr, total, scale, op);
|
||||
}
|
||||
else if (srcDepth == CV_8S && dstDepth == CV_16S)
|
||||
{
|
||||
muldiv_((const schar*)sptr1, (const schar*)sptr2, (short*)dptr, total, scale, op);
|
||||
}
|
||||
else if (srcDepth == CV_8U && dstDepth == CV_32F)
|
||||
{
|
||||
muldiv_((const uchar*)sptr1, (const uchar*)sptr2, (float*)dptr, total, scale, op);
|
||||
}
|
||||
else if (srcDepth == CV_8S && dstDepth == CV_32F)
|
||||
{
|
||||
muldiv_((const schar*)sptr1, (const schar*)sptr2, (float*)dptr, total, scale, op);
|
||||
}
|
||||
else
|
||||
{
|
||||
CV_Error(Error::StsUnsupportedFormat, "This format combination is not supported yet");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void multiply(const Mat& src1, const Mat& src2, Mat& dst, double scale)
|
||||
void multiply(const Mat& src1, const Mat& src2, Mat& dst, double scale, int ctype)
|
||||
{
|
||||
muldiv( src1, src2, dst, scale, '*' );
|
||||
muldiv( src1, src2, dst, ctype, scale, '*' );
|
||||
}
|
||||
|
||||
void divide(const Mat& src1, const Mat& src2, Mat& dst, double scale)
|
||||
void divide(const Mat& src1, const Mat& src2, Mat& dst, double scale, int ctype)
|
||||
{
|
||||
muldiv( src1, src2, dst, scale, '/' );
|
||||
muldiv( src1, src2, dst, ctype, scale, '/' );
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user