mirror of
https://github.com/opencv/opencv.git
synced 2025-08-05 22:19:14 +08:00
Merge pull request #25902 from asmorkalov:as/core_mask_cvbool
Mask support with CV_Bool in ts and core #25902 Partially cover https://github.com/opencv/opencv/issues/25895 ### 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. - [ ] The feature is well documented and sample code can be built with the project CMake
This commit is contained in:
parent
8ba70194b1
commit
459a9c60ed
@ -352,8 +352,8 @@ result of an incorrect sign in the case of overflow.
|
||||
@param src2 second input array or a scalar.
|
||||
@param dst output array that has the same size and number of channels as the input array(s); the
|
||||
depth is defined by dtype or src1/src2.
|
||||
@param mask optional operation mask - 8-bit single channel array, that specifies elements of the
|
||||
output array to be changed.
|
||||
@param mask optional operation mask - CV_8U, CV_8S or CV_Bool single channel array, that specifies elements
|
||||
of the output array to be changed.
|
||||
@param dtype optional depth of the output array (see the discussion below).
|
||||
@sa subtract, addWeighted, scaleAdd, Mat::convertTo
|
||||
*/
|
||||
@ -395,7 +395,7 @@ result of an incorrect sign in the case of overflow.
|
||||
@param src1 first input array or a scalar.
|
||||
@param src2 second input array or a scalar.
|
||||
@param dst output array of the same size and the same number of channels as the input array.
|
||||
@param mask optional operation mask; this is an 8-bit single channel array that specifies elements
|
||||
@param mask optional operation mask; this is CV_8U, CV8S or CV_Bool single channel array that specifies elements
|
||||
of the output array to be changed.
|
||||
@param dtype optional depth of the output array
|
||||
@sa add, addWeighted, scaleAdd, Mat::convertTo
|
||||
@ -669,7 +669,7 @@ independently for each channel, and return it:
|
||||
When all the mask elements are 0's, the function returns Scalar::all(0)
|
||||
@param src input array that should have from 1 to 4 channels so that the result can be stored in
|
||||
Scalar_ .
|
||||
@param mask optional operation mask.
|
||||
@param mask optional operation mask ot type CV_8U, CV_8S or CV_Bool.
|
||||
@sa countNonZero, meanStdDev, norm, minMaxLoc
|
||||
*/
|
||||
CV_EXPORTS_W Scalar mean(InputArray src, InputArray mask = noArray());
|
||||
@ -691,7 +691,7 @@ then pass the matrix to calcCovarMatrix .
|
||||
Scalar_ 's.
|
||||
@param mean output parameter: calculated mean value.
|
||||
@param stddev output parameter: calculated standard deviation.
|
||||
@param mask optional operation mask.
|
||||
@param mask optional operation mask of type CV_8U, CV_8S or CV_Bool.
|
||||
@sa countNonZero, mean, norm, minMaxLoc, calcCovarMatrix
|
||||
*/
|
||||
CV_EXPORTS_W void meanStdDev(InputArray src, OutputArray mean, OutputArray stddev,
|
||||
@ -731,7 +731,7 @@ Hamming norms can only be calculated with CV_8U depth arrays.
|
||||
|
||||
@param src1 first input array.
|
||||
@param normType type of the norm (see #NormTypes).
|
||||
@param mask optional operation mask; it must have the same size as src1 and CV_8UC1 type.
|
||||
@param mask optional operation mask; it must have the same size as src1 and type CV_8UC1, CV_8SC1 or CV_BoolC1.
|
||||
*/
|
||||
CV_EXPORTS_W double norm(InputArray src1, int normType = NORM_L2, InputArray mask = noArray());
|
||||
|
||||
@ -744,7 +744,7 @@ The type of norm to calculate is specified using #NormTypes.
|
||||
@param src1 first input array.
|
||||
@param src2 second input array of the same size and the same type as src1.
|
||||
@param normType type of the norm (see #NormTypes).
|
||||
@param mask optional operation mask; it must have the same size as src1 and CV_8UC1 type.
|
||||
@param mask optional operation mask; it must have the same size as src1 and type CV_8UC1, CV_8S1 or CV_BoolC1.
|
||||
*/
|
||||
CV_EXPORTS_W double norm(InputArray src1, InputArray src2,
|
||||
int normType = NORM_L2, InputArray mask = noArray());
|
||||
@ -841,7 +841,7 @@ normalization.
|
||||
@param norm_type normalization type (see cv::NormTypes).
|
||||
@param dtype when negative, the output array has the same type as src; otherwise, it has the same
|
||||
number of channels as src and the depth =CV_MAT_DEPTH(dtype).
|
||||
@param mask optional operation mask.
|
||||
@param mask optional operation mask of type CV_8U, CV_8S or CV_Bool.
|
||||
@sa norm, Mat::convertTo, SparseMat::convertTo
|
||||
*/
|
||||
CV_EXPORTS_W void normalize( InputArray src, InputOutputArray dst, double alpha = 1, double beta = 0,
|
||||
@ -872,7 +872,7 @@ mixChannels, or split.
|
||||
@param maxVal pointer to the returned maximum value; NULL is used if not required.
|
||||
@param minLoc pointer to the returned minimum location (in 2D case); NULL is used if not required.
|
||||
@param maxLoc pointer to the returned maximum location (in 2D case); NULL is used if not required.
|
||||
@param mask optional mask used to select a sub-array.
|
||||
@param mask optional mask used to select a sub-array of type CV_8U, CV_8S or CV_Bool.
|
||||
@sa max, min, reduceArgMin, reduceArgMax, compare, inRange, extractImageCOI, mixChannels, split, Mat::reshape
|
||||
*/
|
||||
CV_EXPORTS_W void minMaxLoc(InputArray src, CV_OUT double* minVal,
|
||||
@ -1359,7 +1359,7 @@ converted to the array type.
|
||||
@param src2 second input array or a scalar.
|
||||
@param dst output array that has the same size and type as the input
|
||||
arrays.
|
||||
@param mask optional operation mask, 8-bit single channel array, that
|
||||
@param mask optional operation mask, CV_8U, CV_8S or CV_Bool single channel array, that
|
||||
specifies elements of the output array to be changed.
|
||||
*/
|
||||
CV_EXPORTS_W void bitwise_and(InputArray src1, InputArray src2,
|
||||
@ -1386,7 +1386,7 @@ converted to the array type.
|
||||
@param src2 second input array or a scalar.
|
||||
@param dst output array that has the same size and type as the input
|
||||
arrays.
|
||||
@param mask optional operation mask, 8-bit single channel array, that
|
||||
@param mask optional operation mask, CV_8U, CV_8S or CV_Bool single channel array, that
|
||||
specifies elements of the output array to be changed.
|
||||
*/
|
||||
CV_EXPORTS_W void bitwise_or(InputArray src1, InputArray src2,
|
||||
@ -1414,7 +1414,7 @@ converted to the array type.
|
||||
@param src2 second input array or a scalar.
|
||||
@param dst output array that has the same size and type as the input
|
||||
arrays.
|
||||
@param mask optional operation mask, 8-bit single channel array, that
|
||||
@param mask optional operation mask, CV_8U, CV_8S or CV_Bool single channel array, that
|
||||
specifies elements of the output array to be changed.
|
||||
*/
|
||||
CV_EXPORTS_W void bitwise_xor(InputArray src1, InputArray src2,
|
||||
@ -1431,7 +1431,7 @@ case of multi-channel arrays, each channel is processed independently.
|
||||
@param src input array.
|
||||
@param dst output array that has the same size and type as the input
|
||||
array.
|
||||
@param mask optional operation mask, 8-bit single channel array, that
|
||||
@param mask optional operation mask, CV_8U, CV_8S or CV_Bool single channel array, that
|
||||
specifies elements of the output array to be changed.
|
||||
*/
|
||||
CV_EXPORTS_W void bitwise_not(InputArray src, OutputArray dst,
|
||||
@ -1472,7 +1472,7 @@ When the operation mask is specified, if the Mat::create call shown above reallo
|
||||
@param dst Destination matrix. If it does not have a proper size or type before the operation, it is
|
||||
reallocated.
|
||||
@param mask Operation mask of the same size as \*this. Its non-zero elements indicate which matrix
|
||||
elements need to be copied. The mask has to be of type CV_8U and can have 1 or multiple channels.
|
||||
elements need to be copied. The mask has to be of type CV_8U, CV_8S or CV_Bool and can have 1 or multiple channels.
|
||||
*/
|
||||
|
||||
void CV_EXPORTS_W copyTo(InputArray src, OutputArray dst, InputArray mask);
|
||||
|
@ -1232,7 +1232,8 @@ public:
|
||||
@param m Destination matrix. If it does not have a proper size or type before the operation, it is
|
||||
reallocated.
|
||||
@param mask Operation mask of the same size as \*this. Its non-zero elements indicate which matrix
|
||||
elements need to be copied. The mask has to be of type CV_8U and can have 1 or multiple channels.
|
||||
elements need to be copied. The mask has to be of type CV_8U, CV_8S or CV_Bool and can have 1 or
|
||||
multiple channels.
|
||||
*/
|
||||
void copyTo( OutputArray m, InputArray mask ) const;
|
||||
|
||||
@ -1269,7 +1270,8 @@ public:
|
||||
This is an advanced variant of the Mat::operator=(const Scalar& s) operator.
|
||||
@param value Assigned scalar converted to the actual array type.
|
||||
@param mask Operation mask of the same size as \*this. Its non-zero elements indicate which matrix
|
||||
elements need to be copied. The mask has to be of type CV_8U and can have 1 or multiple channels
|
||||
elements need to be copied. The mask has to be of type CV_8U, CV_8S or CV_Bool and can have 1 or
|
||||
multiple channels.
|
||||
*/
|
||||
Mat& setTo(InputArray value, InputArray mask=noArray());
|
||||
|
||||
|
@ -227,7 +227,7 @@ static void binary_op( InputArray _src1, InputArray _src2, OutputArray _dst,
|
||||
if( haveMask )
|
||||
{
|
||||
int mtype = _mask.type();
|
||||
CV_Assert( (mtype == CV_8U || mtype == CV_8S) && _mask.sameSize(*psrc1));
|
||||
CV_Assert( (mtype == CV_8U || mtype == CV_8S || mtype == CV_Bool) && _mask.sameSize(*psrc1));
|
||||
copymask = getCopyMaskFunc(esz);
|
||||
reallocate = !_dst.sameSize(*psrc1) || _dst.type() != type1;
|
||||
}
|
||||
@ -739,7 +739,7 @@ static void arithm_op(InputArray _src1, InputArray _src2, OutputArray _dst,
|
||||
if( haveMask )
|
||||
{
|
||||
int mtype = _mask.type();
|
||||
CV_Assert( (mtype == CV_8UC1 || mtype == CV_8SC1) && _mask.sameSize(*psrc1) );
|
||||
CV_Assert( (mtype == CV_8UC1 || mtype == CV_8SC1 || mtype == CV_Bool) && _mask.sameSize(*psrc1) );
|
||||
reallocate = !_dst.sameSize(*psrc1) || _dst.type() != dtype;
|
||||
}
|
||||
|
||||
@ -1261,7 +1261,7 @@ static BinaryFuncC getCmpFunc(int depth)
|
||||
(BinaryFuncC)cv::hal::cmp64f,
|
||||
(BinaryFuncC)cv::hal::cmp16f,
|
||||
(BinaryFuncC)cv::hal::cmp16bf,
|
||||
0,
|
||||
(BinaryFuncC)GET_OPTIMIZED(cv::hal::cmp8u),
|
||||
(BinaryFuncC)cv::hal::cmp64u,
|
||||
(BinaryFuncC)cv::hal::cmp64s,
|
||||
(BinaryFuncC)cv::hal::cmp32u,
|
||||
|
@ -454,7 +454,7 @@ void Mat::copyTo( OutputArray _dst, InputArray _mask ) const
|
||||
}
|
||||
|
||||
int cn = channels(), mcn = mask.channels();
|
||||
CV_Assert( mask.depth() == CV_8U && (mcn == 1 || mcn == cn) );
|
||||
CV_Assert( (mask.depth() == CV_8U || mask.depth() == CV_8S || mask.depth() == CV_Bool) && (mcn == 1 || mcn == cn) );
|
||||
bool colorMask = mcn > 1;
|
||||
if( dims <= 2 )
|
||||
{
|
||||
@ -643,7 +643,8 @@ Mat& Mat::setTo(InputArray _value, InputArray _mask)
|
||||
|
||||
CV_Assert( checkScalar(value, type(), _value.kind(), _InputArray::MAT ));
|
||||
int cn = channels(), mcn = mask.channels();
|
||||
CV_Assert( mask.empty() || (mask.depth() == CV_8U && (mcn == 1 || mcn == cn) && size == mask.size) );
|
||||
CV_Assert( mask.empty() || ((mask.depth() == CV_8U || mask.depth() == CV_8S || mask.depth() == CV_Bool) &&
|
||||
(mcn == 1 || mcn == cn) && size == mask.size) );
|
||||
|
||||
CV_IPP_RUN_FAST(ipp_Mat_setTo_Mat(*this, value, mask), *this)
|
||||
|
||||
|
@ -126,7 +126,7 @@ Scalar mean(InputArray _src, InputArray _mask)
|
||||
CV_INSTRUMENT_REGION();
|
||||
|
||||
Mat src = _src.getMat(), mask = _mask.getMat();
|
||||
CV_Assert( mask.empty() || mask.type() == CV_8U );
|
||||
CV_Assert( mask.empty() || mask.type() == CV_8U || mask.type() == CV_8S || mask.type() == CV_Bool);
|
||||
|
||||
int k, cn = src.channels(), depth = src.depth();
|
||||
Scalar s;
|
||||
@ -227,7 +227,7 @@ static bool ocl_meanStdDev( InputArray _src, OutputArray _mean, OutputArray _sdv
|
||||
int ddepth = std::max(CV_32S, depth), sqddepth = std::max(CV_32F, depth),
|
||||
dtype = CV_MAKE_TYPE(ddepth, cn),
|
||||
sqdtype = CV_MAKETYPE(sqddepth, cn);
|
||||
CV_Assert(!haveMask || _mask.type() == CV_8UC1);
|
||||
CV_Assert(!haveMask || _mask.type() == CV_8U || _mask.type() == CV_8S || _mask.type() == CV_Bool);
|
||||
|
||||
int wgs2_aligned = 1;
|
||||
while (wgs2_aligned < (int)wgs)
|
||||
@ -461,14 +461,14 @@ void meanStdDev(InputArray _src, OutputArray _mean, OutputArray _sdv, InputArray
|
||||
CV_INSTRUMENT_REGION();
|
||||
|
||||
CV_Assert(!_src.empty());
|
||||
CV_Assert( _mask.empty() || _mask.type() == CV_8UC1 );
|
||||
CV_Assert( _mask.empty() || _mask.type() == CV_8U || _mask.type() == CV_8S || _mask.type() == CV_Bool );
|
||||
|
||||
CV_OCL_RUN(OCL_PERFORMANCE_CHECK(_src.isUMat()) && _src.dims() <= 2,
|
||||
ocl_meanStdDev(_src, _mean, _sdv, _mask))
|
||||
|
||||
Mat src = _src.getMat(), mask = _mask.getMat();
|
||||
|
||||
CV_Assert(mask.empty() || src.size == mask.size);
|
||||
CV_Assert(mask.empty() || ((mask.type() == CV_8U || mask.type() == CV_8S || mask.type() == CV_Bool) && src.size == mask.size));
|
||||
|
||||
CV_IPP_RUN(IPP_VERSION_X100 >= 700, ipp_meanStdDev(src, _mean, _sdv, mask));
|
||||
|
||||
|
@ -171,7 +171,7 @@ bool ocl_minMaxIdx( InputArray _src, double* minVal, double* maxVal, int* minLoc
|
||||
if ((haveMask || type == CV_32FC1) && dev.isAMD())
|
||||
return false;
|
||||
|
||||
CV_Assert( (cn == 1 && (!haveMask || _mask.type() == CV_8U)) ||
|
||||
CV_Assert( (cn == 1 && (!haveMask || _mask.type() == CV_8U || _mask.type() == CV_8S || _mask.type() == CV_Bool)) ||
|
||||
(cn >= 1 && !minLoc && !maxLoc) );
|
||||
|
||||
if (ddepth < 0)
|
||||
@ -302,8 +302,8 @@ void cv::minMaxIdx(InputArray _src, double* minVal,
|
||||
CV_INSTRUMENT_REGION();
|
||||
|
||||
int type = _src.type(), depth = CV_MAT_DEPTH(type), cn = CV_MAT_CN(type);
|
||||
CV_Assert( (cn == 1 && (_mask.empty() || _mask.type() == CV_8U)) ||
|
||||
(cn > 1 && _mask.empty() && !minIdx && !maxIdx) );
|
||||
CV_Assert( (cn == 1 && (_mask.empty() || _mask.type() == CV_8U || _mask.type() == CV_8S || _mask.type() == CV_Bool)) ||
|
||||
(cn > 1 && _mask.empty() && !minIdx && !maxIdx) );
|
||||
|
||||
CV_OCL_RUN(OCL_PERFORMANCE_CHECK(_src.isUMat()) && _src.dims() <= 2 && (_mask.empty() || _src.size() == _mask.size()),
|
||||
ocl_minMaxIdx(_src, minVal, maxVal, minIdx, maxIdx, _mask))
|
||||
|
@ -744,7 +744,7 @@ double norm( InputArray _src, int normType, InputArray _mask )
|
||||
}
|
||||
}
|
||||
|
||||
CV_Assert( mask.empty() || mask.type() == CV_8U );
|
||||
CV_Assert( mask.empty() || mask.type() == CV_8U || mask.type() == CV_8S || mask.type() == CV_Bool );
|
||||
|
||||
if( normType == NORM_HAMMING || normType == NORM_HAMMING2 )
|
||||
{
|
||||
@ -1197,7 +1197,7 @@ double norm( InputArray _src1, InputArray _src2, int normType, InputArray _mask
|
||||
}
|
||||
}
|
||||
|
||||
CV_Assert( mask.empty() || mask.type() == CV_8U );
|
||||
CV_Assert( mask.empty() || mask.type() == CV_8U || mask.type() == CV_8S || mask.type() == CV_Bool );
|
||||
|
||||
if( normType == NORM_HAMMING || normType == NORM_HAMMING2 )
|
||||
{
|
||||
|
@ -56,7 +56,7 @@ bool ocl_sum( InputArray _src, Scalar & res, int sum_op, InputArray _mask,
|
||||
|
||||
int ddepth = std::max(sum_op == OCL_OP_SUM_SQR ? CV_32F : CV_32S, depth),
|
||||
dtype = CV_MAKE_TYPE(ddepth, cn);
|
||||
CV_Assert(!haveMask || _mask.type() == CV_8UC1);
|
||||
CV_Assert(!haveMask || _mask.type() == CV_8U || _mask.type() == CV_8S || _mask.type() == CV_Bool);
|
||||
|
||||
int wgs2_aligned = 1;
|
||||
while (wgs2_aligned < (int)wgs)
|
||||
|
@ -1230,7 +1230,7 @@ void UMat::copyTo(OutputArray _dst, InputArray _mask) const
|
||||
}
|
||||
#ifdef HAVE_OPENCL
|
||||
int cn = channels(), mtype = _mask.type(), mdepth = CV_MAT_DEPTH(mtype), mcn = CV_MAT_CN(mtype);
|
||||
CV_Assert( mdepth == CV_8U && (mcn == 1 || mcn == cn) );
|
||||
CV_Assert( (mdepth == CV_8U || mdepth == CV_8S || mdepth == CV_Bool) && (mcn == 1 || mcn == cn) );
|
||||
|
||||
if (ocl::useOpenCL() && _dst.isUMat() && dims <= 2)
|
||||
{
|
||||
@ -1307,7 +1307,7 @@ UMat& UMat::setTo(InputArray _value, InputArray _mask)
|
||||
if( haveMask )
|
||||
{
|
||||
mask = _mask.getUMat();
|
||||
CV_Assert( mask.size() == size() && mask.type() == CV_8UC1 );
|
||||
CV_Assert( mask.size() == size() && (mask.type() == CV_8U || mask.type() == CV_8S || mask.type() == CV_Bool) );
|
||||
ocl::KernelArg maskarg = ocl::KernelArg::ReadOnlyNoSize(mask),
|
||||
dstarg = ocl::KernelArg::ReadWrite(*this);
|
||||
setK.args(maskarg, dstarg, scalararg);
|
||||
|
@ -2462,23 +2462,22 @@ TEST(Compare, regression_16F_do_not_crash)
|
||||
EXPECT_NO_THROW(cv::compare(mat1, mat2, dst, cv::CMP_EQ));
|
||||
}
|
||||
|
||||
|
||||
TEST(Core_minMaxIdx, regression_9207_1)
|
||||
{
|
||||
const int rows = 4;
|
||||
const int cols = 3;
|
||||
uchar mask_[rows*cols] = {
|
||||
255, 255, 255,
|
||||
255, 0, 255,
|
||||
0, 255, 255,
|
||||
0, 0, 255
|
||||
};
|
||||
255, 255, 255,
|
||||
255, 0, 255,
|
||||
0, 255, 255,
|
||||
0, 0, 255
|
||||
};
|
||||
uchar src_[rows*cols] = {
|
||||
1, 1, 1,
|
||||
1, 1, 1,
|
||||
2, 1, 1,
|
||||
2, 2, 1
|
||||
};
|
||||
1, 1, 1,
|
||||
1, 1, 1,
|
||||
2, 1, 1,
|
||||
2, 2, 1
|
||||
};
|
||||
Mat mask(Size(cols, rows), CV_8UC1, mask_);
|
||||
Mat src(Size(cols, rows), CV_8UC1, src_);
|
||||
double minVal = -0.0, maxVal = -0.0;
|
||||
@ -2490,7 +2489,6 @@ TEST(Core_minMaxIdx, regression_9207_1)
|
||||
EXPECT_EQ(0, maxIdx[1]);
|
||||
}
|
||||
|
||||
|
||||
class TransposeND : public testing::TestWithParam< tuple<std::vector<int>, perf::MatType> >
|
||||
{
|
||||
public:
|
||||
@ -2886,11 +2884,11 @@ TEST(Core_Norm, IPP_regression_NORM_L1_16UC3_small)
|
||||
Mat a(sz, CV_MAKE_TYPE(CV_16U, cn), Scalar::all(1));
|
||||
Mat b(sz, CV_MAKE_TYPE(CV_16U, cn), Scalar::all(2));
|
||||
uchar mask_[9*4] = {
|
||||
255, 255, 255, 0, 255, 255, 0, 255, 0,
|
||||
0, 255, 0, 0, 255, 255, 255, 255, 0,
|
||||
0, 0, 0, 255, 0, 255, 0, 255, 255,
|
||||
0, 0, 255, 0, 255, 255, 255, 0, 255
|
||||
};
|
||||
255, 255, 255, 0, 255, 255, 0, 255, 0,
|
||||
0, 255, 0, 0, 255, 255, 255, 255, 0,
|
||||
0, 0, 0, 255, 0, 255, 0, 255, 255,
|
||||
0, 0, 255, 0, 255, 255, 255, 0, 255
|
||||
};
|
||||
Mat mask(sz, CV_8UC1, mask_);
|
||||
|
||||
EXPECT_EQ((double)9*4*cn, cv::norm(a, b, NORM_L1)); // without mask, IPP works well
|
||||
@ -3622,7 +3620,169 @@ TEST_P(Core_LUT, accuracy_multi)
|
||||
ASSERT_EQ(0, cv::norm(output, gt, cv::NORM_INF));
|
||||
}
|
||||
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(/**/, Core_LUT, perf::MatDepth::all());
|
||||
|
||||
CV_ENUM(MaskType, CV_8U, CV_8S, CV_Bool)
|
||||
typedef testing::TestWithParam<MaskType> Core_MaskTypeTest;
|
||||
|
||||
TEST_P(Core_MaskTypeTest, BasicArithm)
|
||||
{
|
||||
int mask_type = GetParam();
|
||||
RNG& rng = theRNG();
|
||||
const int MAX_DIM=3;
|
||||
int sizes[MAX_DIM];
|
||||
for( int iter = 0; iter < 100; iter++ )
|
||||
{
|
||||
int dims = rng.uniform(1, MAX_DIM+1);
|
||||
int depth = rng.uniform(CV_8U, CV_64F+1);
|
||||
int cn = rng.uniform(1, 6);
|
||||
int type = CV_MAKETYPE(depth, cn);
|
||||
int op = rng.uniform(0, depth < CV_32F ? 5 : 2); // don't run binary operations between floating-point values
|
||||
int depth1 = op <= 1 ? CV_64F : depth;
|
||||
for (int k = 0; k < MAX_DIM; k++)
|
||||
{
|
||||
sizes[k] = k < dims ? rng.uniform(1, 30) : 0;
|
||||
}
|
||||
|
||||
Mat a(dims, sizes, type), a1;
|
||||
Mat b(dims, sizes, type), b1;
|
||||
Mat mask(dims, sizes, mask_type);
|
||||
Mat mask1;
|
||||
Mat c, d;
|
||||
|
||||
rng.fill(a, RNG::UNIFORM, 0, 100);
|
||||
rng.fill(b, RNG::UNIFORM, 0, 100);
|
||||
|
||||
// [-2,2) range means that the each generated random number
|
||||
// will be one of -2, -1, 0, 1. Saturated to [0,255], it will become
|
||||
// 0, 0, 0, 1 => the mask will be filled by ~25%.
|
||||
rng.fill(mask, RNG::UNIFORM, -2, 2);
|
||||
|
||||
a.convertTo(a1, depth1);
|
||||
b.convertTo(b1, depth1);
|
||||
// invert the mask
|
||||
cv::compare(mask, 0, mask1, CMP_EQ);
|
||||
a1.setTo(0, mask1);
|
||||
b1.setTo(0, mask1);
|
||||
|
||||
if( op == 0 )
|
||||
{
|
||||
cv::add(a, b, c, mask);
|
||||
cv::add(a1, b1, d);
|
||||
}
|
||||
else if( op == 1 )
|
||||
{
|
||||
cv::subtract(a, b, c, mask);
|
||||
cv::subtract(a1, b1, d);
|
||||
}
|
||||
else if( op == 2 )
|
||||
{
|
||||
cv::bitwise_and(a, b, c, mask);
|
||||
cv::bitwise_and(a1, b1, d);
|
||||
}
|
||||
else if( op == 3 )
|
||||
{
|
||||
cv::bitwise_or(a, b, c, mask);
|
||||
cv::bitwise_or(a1, b1, d);
|
||||
}
|
||||
else if( op == 4 )
|
||||
{
|
||||
cv::bitwise_xor(a, b, c, mask);
|
||||
cv::bitwise_xor(a1, b1, d);
|
||||
}
|
||||
Mat d1;
|
||||
d.convertTo(d1, depth);
|
||||
EXPECT_LE(cvtest::norm(c, d1, NORM_INF), DBL_EPSILON);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_P(Core_MaskTypeTest, MinMaxIdx)
|
||||
{
|
||||
int mask_type = GetParam();
|
||||
const int rows = 4;
|
||||
const int cols = 3;
|
||||
uchar mask_[rows*cols] = {
|
||||
255, 255, 1,
|
||||
255, 0, 255,
|
||||
0, 1, 255,
|
||||
0, 0, 255
|
||||
};
|
||||
uchar src_[rows*cols] = {
|
||||
1, 1, 1,
|
||||
1, 1, 1,
|
||||
2, 1, 1,
|
||||
2, 2, 1
|
||||
};
|
||||
Mat mask(Size(cols, rows), mask_type, mask_);
|
||||
Mat src(Size(cols, rows), CV_8UC1, src_);
|
||||
double minVal = -0.0, maxVal = -0.0;
|
||||
int minIdx[2] = { -2, -2 }, maxIdx[2] = { -2, -2 };
|
||||
cv::minMaxIdx(src, &minVal, &maxVal, minIdx, maxIdx, mask);
|
||||
EXPECT_EQ(0, minIdx[0]);
|
||||
EXPECT_EQ(0, minIdx[1]);
|
||||
EXPECT_EQ(0, maxIdx[0]);
|
||||
EXPECT_EQ(0, maxIdx[1]);
|
||||
}
|
||||
|
||||
TEST_P(Core_MaskTypeTest, Norm)
|
||||
{
|
||||
int mask_type = GetParam();
|
||||
int cn = 3;
|
||||
Size sz(9, 4); // width < 16
|
||||
Mat a(sz, CV_MAKE_TYPE(CV_16U, cn), Scalar::all(1));
|
||||
Mat b(sz, CV_MAKE_TYPE(CV_16U, cn), Scalar::all(2));
|
||||
uchar mask_[9*4] = {
|
||||
255, 255, 255, 0, 1, 255, 0, 255, 0,
|
||||
0, 255, 0, 0, 255, 255, 255, 255, 0,
|
||||
0, 0, 0, 255, 0, 1, 0, 255, 255,
|
||||
0, 0, 255, 0, 255, 255, 1, 0, 255
|
||||
};
|
||||
Mat mask(sz, mask_type, mask_);
|
||||
|
||||
EXPECT_EQ((double)9*4*cn, cv::norm(a, b, NORM_L1)); // without mask, IPP works well
|
||||
EXPECT_EQ((double)20*cn, cv::norm(a, b, NORM_L1, mask));
|
||||
}
|
||||
|
||||
TEST_P(Core_MaskTypeTest, Mean)
|
||||
{
|
||||
int mask_type = GetParam();
|
||||
Size sz(9, 4);
|
||||
Mat a(sz, CV_16UC1, Scalar::all(1));
|
||||
uchar mask_[9*4] = {
|
||||
255, 255, 255, 0, 1, 255, 0, 255, 0,
|
||||
0, 255, 0, 0, 255, 255, 255, 255, 0,
|
||||
0, 0, 0, 1, 0, 255, 0, 1, 255,
|
||||
0, 0, 255, 0, 255, 255, 255, 0, 255
|
||||
};
|
||||
Mat mask(sz, mask_type, mask_);
|
||||
a.setTo(2, mask);
|
||||
|
||||
Scalar result = cv::mean(a, mask);
|
||||
EXPECT_NEAR(result[0], 2, 1e-6);
|
||||
}
|
||||
|
||||
TEST_P(Core_MaskTypeTest, MeanStdDev)
|
||||
{
|
||||
int mask_type = GetParam();
|
||||
Size sz(9, 4);
|
||||
Mat a(sz, CV_16UC1, Scalar::all(1));
|
||||
uchar mask_[9*4] = {
|
||||
255, 255, 255, 0, 1, 255, 0, 255, 0,
|
||||
0, 255, 0, 0, 255, 255, 255, 255, 0,
|
||||
0, 0, 0, 1, 0, 255, 0, 1, 255,
|
||||
0, 0, 255, 0, 255, 255, 255, 0, 255
|
||||
};
|
||||
Mat mask(sz, mask_type, mask_);
|
||||
a.setTo(2, mask);
|
||||
|
||||
Scalar m, stddev;
|
||||
cv::meanStdDev(a, m, stddev, mask);
|
||||
|
||||
EXPECT_NEAR(m[0], 2, 1e-6);
|
||||
EXPECT_NEAR(stddev[0], 0, 1e-6);
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(/**/, Core_MaskTypeTest, MaskType::all());
|
||||
|
||||
|
||||
}} // namespace
|
||||
|
@ -431,7 +431,7 @@ void copy(const Mat& src, Mat& dst, const Mat& mask, bool invertMask)
|
||||
}
|
||||
|
||||
int mcn = mask.channels();
|
||||
CV_Assert( src.size == mask.size && mask.depth() == CV_8U
|
||||
CV_Assert( src.size == mask.size && (mask.depth() == CV_8U || mask.depth() == CV_Bool)
|
||||
&& (mcn == 1 || mcn == src.channels()) );
|
||||
|
||||
const Mat *arrays[]={&src, &dst, &mask, 0};
|
||||
@ -1397,7 +1397,7 @@ double norm(InputArray _src, int normType, InputArray _mask)
|
||||
int normType0 = normType;
|
||||
normType = normType == NORM_L2SQR ? NORM_L2 : normType;
|
||||
|
||||
CV_Assert( mask.empty() || (src.size == mask.size && mask.type() == CV_8U) );
|
||||
CV_Assert( mask.empty() || (src.size == mask.size && (mask.type() == CV_8U || mask.type() == CV_Bool)) );
|
||||
CV_Assert( normType == NORM_INF || normType == NORM_L1 || normType == NORM_L2 );
|
||||
|
||||
const Mat *arrays[]={&src, &mask, 0};
|
||||
@ -1506,7 +1506,7 @@ double norm(InputArray _src1, InputArray _src2, int normType, InputArray _mask)
|
||||
|
||||
CV_CheckTypeEQ(src1.type(), src2.type(), "");
|
||||
CV_Assert(src1.size == src2.size);
|
||||
CV_Assert( mask.empty() || (src1.size == mask.size && mask.type() == CV_8U) );
|
||||
CV_Assert( mask.empty() || (src1.size == mask.size && (mask.type() == CV_8U || mask.type() == CV_Bool)) );
|
||||
CV_Assert( normType == NORM_INF || normType == NORM_L1 || normType == NORM_L2 );
|
||||
const Mat *arrays[]={&src1, &src2, &mask, 0};
|
||||
Mat planes[3];
|
||||
@ -2937,7 +2937,7 @@ mean_(const _Tp* src, const uchar* mask, size_t total, int cn, Scalar& sum, int&
|
||||
|
||||
Scalar mean(const Mat& src, const Mat& mask)
|
||||
{
|
||||
CV_Assert(mask.empty() || (mask.type() == CV_8U && mask.size == src.size));
|
||||
CV_Assert(mask.empty() || ((mask.type() == CV_8U || mask.type() == CV_Bool) && mask.size == src.size));
|
||||
Scalar sum;
|
||||
int nz = 0;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user