Skip to content

Commit 64d3111

Browse files
authored
Merge pull request opencv#26459 from savuor:rv/hal_absdiff_scalar
HAL added for absdiff(array, scalar) + related fixes opencv#26459 ### This PR changes * HAL for `absdiff` when one of arguments is a scalar, including multichannel arrays and scalars * several channels support for HAL `addScalar` * proper data type check for `addScalar` when one of arguments is a scalar ### 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 - [ ] There is a reference to the original bug report and related work - [ ] 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
1 parent 64273c8 commit 64d3111

File tree

2 files changed

+117
-15
lines changed

2 files changed

+117
-15
lines changed

modules/core/src/arithm.cpp

Lines changed: 94 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -587,7 +587,7 @@ static bool ocl_arithm_op(InputArray _src1, InputArray _src2, OutputArray _dst,
587587

588588
typedef int (*ScalarFunc)(const uchar* src, size_t step_src,
589589
uchar* dst, size_t step_dst, int width, int height,
590-
void* scalar, bool scalarIsFirst);
590+
void* scalar, bool scalarIsFirst, int nChannels);
591591

592592
typedef int (*ExtendedTypeFunc)(const uchar* src1, size_t step1,
593593
const uchar* src2, size_t step2,
@@ -862,7 +862,6 @@ static void arithm_op(InputArray _src1, InputArray _src2, OutputArray _dst,
862862
for( size_t j = 0; j < total; j += blocksize )
863863
{
864864
int bsz = (int)MIN(total - j, blocksize);
865-
Size bszn(bsz*cn, 1);
866865
const uchar *sptr1 = ptrs[0];
867866
const uchar* sptr2 = buf2;
868867
uchar* dptr = ptrs[1];
@@ -875,30 +874,30 @@ static void arithm_op(InputArray _src1, InputArray _src2, OutputArray _dst,
875874
// try to perform operation in 1 call, fallback to classic way if fail
876875
uchar* opconverted = haveMask ? maskbuf : dptr;
877876
if (!scalarFunc || src2.total() != 1 ||
878-
scalarFunc(extSptr1, 1, opconverted, 1, bszn.width, bszn.height, (void*)extSptr2, swapped12) != 0)
877+
scalarFunc(extSptr1, 1, opconverted, 1, bsz, 1, (void*)extSptr2, swapped12, cn) != 0)
879878
{
880879
// try to perform operation with conversion in one call
881880
// if fail, use converter functions
882881

883882
if (!extendedFunc || extendedFunc(extSptr1, 1, extSptr2, 1, opconverted, 1,
884-
bszn.width, bszn.height, usrdata) != 0)
883+
bsz*cn, 1, usrdata) != 0)
885884
{
886885
if( cvtsrc1 )
887886
{
888-
cvtsrc1( sptr1, 1, 0, 1, buf1, 1, bszn, 0 );
887+
cvtsrc1( sptr1, 1, 0, 1, buf1, 1, Size(bsz*cn, 1), 0 );
889888
sptr1 = buf1;
890889
}
891890

892891
if( swapped12 )
893892
std::swap(sptr1, sptr2);
894893

895894
uchar* fdst = ( haveMask || cvtdst ) ? wbuf : dptr;
896-
func( sptr1, 1, sptr2, 1, fdst, 1, bszn.width, bszn.height, usrdata );
895+
func( sptr1, 1, sptr2, 1, fdst, 1, bsz*cn, 1, usrdata );
897896

898897
if (cvtdst)
899898
{
900899
uchar* cdst = haveMask ? maskbuf : dptr;
901-
cvtdst(wbuf, 1, 0, 1, cdst, 1, bszn, 0);
900+
cvtdst(wbuf, 1, 0, 1, cdst, 1, Size(bsz*cn, 1), 0);
902901
}
903902
opconverted = cvtdst ? maskbuf : wbuf;
904903
}
@@ -931,9 +930,9 @@ static BinaryFuncC* getAddTab()
931930
}
932931

933932
static int addScalar32f32fWrapper(const uchar* src, size_t step_src, uchar* dst, size_t step_dst, int width, int height,
934-
void* scalar, bool /*scalarIsFirst*/)
933+
void* scalar, bool /*scalarIsFirst*/, int nChannels)
935934
{
936-
int res = cv_hal_addScalar32f32f((const float*)src, step_src, (float *)dst, step_dst, width, height, (const float*)scalar);
935+
int res = cv_hal_addScalar32f32f((const float*)src, step_src, (float *)dst, step_dst, width, height, (const float*)scalar, nChannels);
937936
if (res == CV_HAL_ERROR_OK || res == CV_HAL_ERROR_NOT_IMPLEMENTED)
938937
return res;
939938
else
@@ -944,9 +943,9 @@ static int addScalar32f32fWrapper(const uchar* src, size_t step_src, uchar* dst,
944943
}
945944

946945
static int addScalar16s16sWrapper(const uchar* src, size_t step_src, uchar* dst, size_t step_dst, int width, int height,
947-
void* scalar, bool /*scalarIsFirst*/)
946+
void* scalar, bool /*scalarIsFirst*/, int nChannels)
948947
{
949-
int res = cv_hal_addScalar16s16s((const int16_t*)src, step_src, (int16_t *)dst, step_dst, width, height, (const int16_t*)scalar);
948+
int res = cv_hal_addScalar16s16s((const int16_t*)src, step_src, (int16_t *)dst, step_dst, width, height, (const int16_t*)scalar, nChannels);
950949
if (res == CV_HAL_ERROR_OK || res == CV_HAL_ERROR_NOT_IMPLEMENTED)
951950
return res;
952951
else
@@ -1042,6 +1041,67 @@ static BinaryFuncC* getAbsDiffTab()
10421041
return absDiffTab;
10431042
}
10441043

1044+
1045+
static int absDiffScalar32f32fWrapper(const uchar* src, size_t step_src, uchar* dst, size_t step_dst, int width, int height,
1046+
void* scalar, bool /*scalarIsFirst*/, int nChannels)
1047+
{
1048+
int res = cv_hal_absDiffScalar32f32f((const float*)src, step_src, (float *)dst, step_dst, width, height, (const float*)scalar, nChannels);
1049+
if (res == CV_HAL_ERROR_OK || res == CV_HAL_ERROR_NOT_IMPLEMENTED)
1050+
return res;
1051+
else
1052+
{
1053+
CV_Error_(cv::Error::StsInternal, ("HAL implementation addScalar32f32f ==> " CVAUX_STR(cv_hal_addScalar32f32f)
1054+
" returned %d (0x%08x)", res, res));
1055+
}
1056+
}
1057+
1058+
static int absDiffScalar32s32uWrapper(const uchar* src, size_t step_src, uchar* dst, size_t step_dst, int width, int height,
1059+
void* scalar, bool /*scalarIsFirst*/, int nChannels)
1060+
{
1061+
int res = cv_hal_absDiffScalar32s32u((const int*)src, step_src, (uint32_t*)dst, step_dst, width, height, (const int*)scalar, nChannels);
1062+
if (res == CV_HAL_ERROR_OK || res == CV_HAL_ERROR_NOT_IMPLEMENTED)
1063+
return res;
1064+
else
1065+
{
1066+
CV_Error_(cv::Error::StsInternal, ("HAL implementation addScalar32f32f ==> " CVAUX_STR(cv_hal_addScalar32f32f)
1067+
" returned %d (0x%08x)", res, res));
1068+
}
1069+
}
1070+
1071+
static int absDiffScalar8u8uWrapper(const uchar* src, size_t step_src, uchar* dst, size_t step_dst, int width, int height,
1072+
void* scalar, bool /*scalarIsFirst*/, int nChannels)
1073+
{
1074+
int res = cv_hal_absDiffScalar8u8u((const uchar*)src, step_src, (uchar*)dst, step_dst, width, height, (const uchar*)scalar, nChannels);
1075+
if (res == CV_HAL_ERROR_OK || res == CV_HAL_ERROR_NOT_IMPLEMENTED)
1076+
return res;
1077+
else
1078+
{
1079+
CV_Error_(cv::Error::StsInternal, ("HAL implementation addScalar32f32f ==> " CVAUX_STR(cv_hal_addScalar32f32f)
1080+
" returned %d (0x%08x)", res, res));
1081+
}
1082+
}
1083+
1084+
static ScalarFunc getAbsDiffScalarFunc(int srcType, int dstType)
1085+
{
1086+
if (srcType == CV_32F && dstType == CV_32F)
1087+
{
1088+
return absDiffScalar32f32fWrapper;
1089+
}
1090+
// resulting type is 32U in fact
1091+
else if (srcType == CV_32S && dstType == CV_32S)
1092+
{
1093+
return absDiffScalar32s32uWrapper;
1094+
}
1095+
else if (srcType == CV_8U && dstType == CV_8U)
1096+
{
1097+
return absDiffScalar8u8uWrapper;
1098+
}
1099+
else
1100+
{
1101+
return nullptr;
1102+
}
1103+
}
1104+
10451105
}
10461106

10471107
void cv::add( InputArray src1, InputArray src2, OutputArray dst,
@@ -1056,7 +1116,17 @@ void cv::add( InputArray src1, InputArray src2, OutputArray dst,
10561116
return;
10571117
}
10581118

1059-
ScalarFunc scalarFunc = getAddScalarFunc(src1.depth(), dtype < 0 ? dst.depth() : dtype);
1119+
int sdepth = src1.depth();
1120+
if (checkScalar(src1, src1.type(), src1.kind(), _InputArray::MATX))
1121+
{
1122+
sdepth = src2.depth();
1123+
}
1124+
if (checkScalar(src2, src2.type(), src2.kind(), _InputArray::MATX))
1125+
{
1126+
sdepth = src1.depth();
1127+
}
1128+
1129+
ScalarFunc scalarFunc = getAddScalarFunc(sdepth, dtype < 0 ? dst.depth() : dtype);
10601130
arithm_op(src1, src2, dst, mask, dtype, getAddTab(), false, 0, OCL_OP_ADD, nullptr,
10611131
/* scalarFunc */ scalarFunc );
10621132
}
@@ -1089,7 +1159,18 @@ void cv::absdiff( InputArray src1, InputArray src2, OutputArray dst )
10891159
return;
10901160
}
10911161

1092-
arithm_op(src1, src2, dst, noArray(), -1, getAbsDiffTab(), false, 0, OCL_OP_ABSDIFF);
1162+
int sdepth = src1.depth();
1163+
if (checkScalar(src1, src1.type(), src1.kind(), _InputArray::MATX))
1164+
{
1165+
sdepth = src2.depth();
1166+
}
1167+
if (checkScalar(src2, src2.type(), src2.kind(), _InputArray::MATX))
1168+
{
1169+
sdepth = src1.depth();
1170+
}
1171+
ScalarFunc scalarFunc = getAbsDiffScalarFunc(sdepth, dst.depth());
1172+
arithm_op(src1, src2, dst, noArray(), -1, getAbsDiffTab(), false, 0, OCL_OP_ABSDIFF,
1173+
/* extendedFunc */ nullptr, scalarFunc);
10931174
}
10941175

10951176
void cv::copyTo(InputArray _src, OutputArray _dst, InputArray _mask)

modules/core/src/hal_replacement.hpp

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -109,9 +109,10 @@ Add scalar: _dst[i] = src[i] + scalar
109109
@param width width of the images
110110
@param height height of the images
111111
@param scalar_data pointer to scalar value
112+
@param nChannels number of channels per element
112113
*/
113-
inline int hal_ni_addScalar32f32f(const float *src_data, size_t src_step, float *dst_data, size_t dst_step, int width, int height, const float* scalar_data) { return CV_HAL_ERROR_NOT_IMPLEMENTED; }
114-
inline int hal_ni_addScalar16s16s(const int16_t *src_data, size_t src_step, int16_t *dst_data, size_t dst_step, int width, int height, const int16_t* scalar_data) { return CV_HAL_ERROR_NOT_IMPLEMENTED; }
114+
inline int hal_ni_addScalar32f32f(const float* src_data, size_t src_step, float* dst_data, size_t dst_step, int width, int height, const float* scalar_data, int nChannels) { return CV_HAL_ERROR_NOT_IMPLEMENTED; }
115+
inline int hal_ni_addScalar16s16s(const int16_t* src_data, size_t src_step, int16_t* dst_data, size_t dst_step, int width, int height, const int16_t* scalar_data, int nChannels) { return CV_HAL_ERROR_NOT_IMPLEMENTED; }
115116
//! @}
116117

117118
/**
@@ -165,6 +166,23 @@ inline int hal_ni_absdiff16s(const short *src1_data, size_t src1_step, const sho
165166
inline int hal_ni_absdiff32s(const int *src1_data, size_t src1_step, const int *src2_data, size_t src2_step, int *dst_data, size_t dst_step, int width, int height) { return CV_HAL_ERROR_NOT_IMPLEMENTED; }
166167
inline int hal_ni_absdiff32f(const float *src1_data, size_t src1_step, const float *src2_data, size_t src2_step, float *dst_data, size_t dst_step, int width, int height) { return CV_HAL_ERROR_NOT_IMPLEMENTED; }
167168
inline int hal_ni_absdiff64f(const double *src1_data, size_t src1_step, const double *src2_data, size_t src2_step, double *dst_data, size_t dst_step, int width, int height) { return CV_HAL_ERROR_NOT_IMPLEMENTED; }
169+
170+
/*
171+
Absolute difference with scalar: _dst[i] = | src[i] - scalar |_
172+
173+
@param src_data source image data
174+
@param src_step source image step
175+
@param dst_data destination image data
176+
@param dst_step destination image step
177+
@param width width of the images
178+
@param height height of the images
179+
@param scalar_data pointer to scalar value
180+
@param nChannels number of channels per element
181+
*/
182+
inline int hal_ni_absDiffScalar32f32f(const float* src_data, size_t src_step, float* dst_data, size_t dst_step, int width, int height, const float* scalar_data, int nChannels) { return CV_HAL_ERROR_NOT_IMPLEMENTED; }
183+
inline int hal_ni_absDiffScalar32s32u(const int* src_data, size_t src_step, uint32_t* dst_data, size_t dst_step, int width, int height, const int* scalar_data, int nChannels) { return CV_HAL_ERROR_NOT_IMPLEMENTED; }
184+
inline int hal_ni_absDiffScalar8u8u (const uchar* src_data, size_t src_step, uchar* dst_data, size_t dst_step, int width, int height, const uchar* scalar_data, int nChannels) { return CV_HAL_ERROR_NOT_IMPLEMENTED; }
185+
168186
//! @}
169187

170188
/**
@@ -229,6 +247,9 @@ inline int hal_ni_not8u(const uchar *src_data, size_t src_step, uchar *dst_data,
229247
#define cv_hal_absdiff32s hal_ni_absdiff32s
230248
#define cv_hal_absdiff32f hal_ni_absdiff32f
231249
#define cv_hal_absdiff64f hal_ni_absdiff64f
250+
#define cv_hal_absDiffScalar32f32f hal_ni_absDiffScalar32f32f
251+
#define cv_hal_absDiffScalar32s32u hal_ni_absDiffScalar32s32u
252+
#define cv_hal_absDiffScalar8u8u hal_ni_absDiffScalar8u8u
232253
#define cv_hal_and8u hal_ni_and8u
233254
#define cv_hal_or8u hal_ni_or8u
234255
#define cv_hal_xor8u hal_ni_xor8u

0 commit comments

Comments
 (0)