fixed mask operations with uninitialized output array, added the corresponding test (ticket #1286)
This commit is contained in:
@@ -1027,6 +1027,7 @@ void binary_op(InputArray _src1, InputArray _src2, OutputArray _dst,
|
|||||||
int cn = src1.channels();
|
int cn = src1.channels();
|
||||||
BinaryFunc copymask = 0;
|
BinaryFunc copymask = 0;
|
||||||
Mat mask;
|
Mat mask;
|
||||||
|
bool reallocate = false;
|
||||||
|
|
||||||
if( haveMask )
|
if( haveMask )
|
||||||
{
|
{
|
||||||
@@ -1034,6 +1035,8 @@ void binary_op(InputArray _src1, InputArray _src2, OutputArray _dst,
|
|||||||
CV_Assert( (mask.type() == CV_8UC1 || mask.type() == CV_8SC1) );
|
CV_Assert( (mask.type() == CV_8UC1 || mask.type() == CV_8SC1) );
|
||||||
CV_Assert( mask.size == src1.size );
|
CV_Assert( mask.size == src1.size );
|
||||||
copymask = getCopyMaskFunc(esz);
|
copymask = getCopyMaskFunc(esz);
|
||||||
|
Mat tdst = _dst.getMat();
|
||||||
|
reallocate = tdst.size != src1.size || tdst.type() != src1.type();
|
||||||
}
|
}
|
||||||
|
|
||||||
AutoBuffer<uchar> _buf;
|
AutoBuffer<uchar> _buf;
|
||||||
@@ -1042,6 +1045,11 @@ void binary_op(InputArray _src1, InputArray _src2, OutputArray _dst,
|
|||||||
_dst.create(src1.dims, src1.size, src1.type());
|
_dst.create(src1.dims, src1.size, src1.type());
|
||||||
Mat dst = _dst.getMat();
|
Mat dst = _dst.getMat();
|
||||||
|
|
||||||
|
// if this is mask operation and dst has been reallocated,
|
||||||
|
// we have to
|
||||||
|
if( haveMask && reallocate )
|
||||||
|
dst = Scalar::all(0);
|
||||||
|
|
||||||
if( bitwise )
|
if( bitwise )
|
||||||
{
|
{
|
||||||
func = *tab;
|
func = *tab;
|
||||||
@@ -1214,6 +1222,7 @@ void arithm_op(InputArray _src1, InputArray _src2, OutputArray _dst,
|
|||||||
int kind1 = _src1.kind(), kind2 = _src2.kind();
|
int kind1 = _src1.kind(), kind2 = _src2.kind();
|
||||||
Mat src1 = _src1.getMat(), src2 = _src2.getMat();
|
Mat src1 = _src1.getMat(), src2 = _src2.getMat();
|
||||||
bool haveMask = !_mask.empty();
|
bool haveMask = !_mask.empty();
|
||||||
|
bool reallocate = false;
|
||||||
|
|
||||||
if( kind1 == kind2 && src1.dims <= 2 && src2.dims <= 2 &&
|
if( kind1 == kind2 && src1.dims <= 2 && src2.dims <= 2 &&
|
||||||
src1.size() == src2.size() && src1.type() == src2.type() &&
|
src1.size() == src2.size() && src1.type() == src2.type() &&
|
||||||
@@ -1302,6 +1311,8 @@ void arithm_op(InputArray _src1, InputArray _src2, OutputArray _dst,
|
|||||||
CV_Assert( (mask.type() == CV_8UC1 || mask.type() == CV_8SC1) );
|
CV_Assert( (mask.type() == CV_8UC1 || mask.type() == CV_8SC1) );
|
||||||
CV_Assert( mask.size == src1.size );
|
CV_Assert( mask.size == src1.size );
|
||||||
copymask = getCopyMaskFunc(dsz);
|
copymask = getCopyMaskFunc(dsz);
|
||||||
|
Mat tdst = _dst.getMat();
|
||||||
|
reallocate = tdst.size != src1.size || tdst.type() != dtype;
|
||||||
}
|
}
|
||||||
|
|
||||||
AutoBuffer<uchar> _buf;
|
AutoBuffer<uchar> _buf;
|
||||||
@@ -1310,6 +1321,10 @@ void arithm_op(InputArray _src1, InputArray _src2, OutputArray _dst,
|
|||||||
|
|
||||||
_dst.create(src1.dims, src1.size, dtype);
|
_dst.create(src1.dims, src1.size, dtype);
|
||||||
Mat dst = _dst.getMat();
|
Mat dst = _dst.getMat();
|
||||||
|
|
||||||
|
if( haveMask && reallocate )
|
||||||
|
dst = Scalar::all(0);
|
||||||
|
|
||||||
BinaryFunc func = tab[CV_MAT_DEPTH(wtype)];
|
BinaryFunc func = tab[CV_MAT_DEPTH(wtype)];
|
||||||
|
|
||||||
if( !haveScalar )
|
if( !haveScalar )
|
||||||
|
@@ -1402,4 +1402,90 @@ INSTANTIATE_TEST_CASE_P(Core_MinMaxLoc, ElemWiseTest, ::testing::Values(ElemWise
|
|||||||
INSTANTIATE_TEST_CASE_P(Core_CartToPolarToCart, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new cvtest::CartToPolarToCartOp)));
|
INSTANTIATE_TEST_CASE_P(Core_CartToPolarToCart, ElemWiseTest, ::testing::Values(ElemWiseOpPtr(new cvtest::CartToPolarToCartOp)));
|
||||||
|
|
||||||
|
|
||||||
|
class CV_ArithmMaskTest : public cvtest::BaseTest
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CV_ArithmMaskTest() {}
|
||||||
|
~CV_ArithmMaskTest() {}
|
||||||
|
protected:
|
||||||
|
void run(int)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
RNG& rng = theRNG();
|
||||||
|
const int MAX_DIM=3;
|
||||||
|
int sizes[MAX_DIM];
|
||||||
|
for( int iter = 0; iter < 100; iter++ )
|
||||||
|
{
|
||||||
|
//ts->printf(cvtest::TS::LOG, ".");
|
||||||
|
|
||||||
|
ts->update_context(this, iter, true);
|
||||||
|
int k, dims = rng.uniform(1, MAX_DIM+1), p = 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, 5);
|
||||||
|
int depth1 = op <= 1 ? CV_64F : depth;
|
||||||
|
for( k = 0; k < dims; k++ )
|
||||||
|
{
|
||||||
|
sizes[k] = rng.uniform(1, 30);
|
||||||
|
p *= sizes[k];
|
||||||
|
}
|
||||||
|
Mat a(dims, sizes, type), a1;
|
||||||
|
Mat b(dims, sizes, type), b1;
|
||||||
|
Mat mask(dims, sizes, CV_8U);
|
||||||
|
Mat mask1;
|
||||||
|
Mat c, d;
|
||||||
|
|
||||||
|
// [-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
|
||||||
|
compare(mask, 0, mask1, CMP_EQ);
|
||||||
|
a1.setTo(0, mask1);
|
||||||
|
b1.setTo(0, mask1);
|
||||||
|
|
||||||
|
if( op == 0 )
|
||||||
|
{
|
||||||
|
add(a, b, c, mask);
|
||||||
|
add(a1, b1, d);
|
||||||
|
}
|
||||||
|
else if( op == 1 )
|
||||||
|
{
|
||||||
|
subtract(a, b, c, mask);
|
||||||
|
subtract(a1, b1, d);
|
||||||
|
}
|
||||||
|
else if( op == 2 )
|
||||||
|
{
|
||||||
|
bitwise_and(a, b, c, mask);
|
||||||
|
bitwise_and(a1, b1, d);
|
||||||
|
}
|
||||||
|
else if( op == 3 )
|
||||||
|
{
|
||||||
|
bitwise_or(a, b, c, mask);
|
||||||
|
bitwise_or(a1, b1, d);
|
||||||
|
}
|
||||||
|
else if( op == 4 )
|
||||||
|
{
|
||||||
|
bitwise_xor(a, b, c, mask);
|
||||||
|
bitwise_xor(a1, b1, d);
|
||||||
|
}
|
||||||
|
Mat d1;
|
||||||
|
d.convertTo(d1, depth);
|
||||||
|
CV_Assert( norm(c, d1, CV_C) == 0 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch(...)
|
||||||
|
{
|
||||||
|
ts->set_failed_test_info(cvtest::TS::FAIL_MISMATCH);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
TEST(Core_ArithmMask, uninitialized) { CV_ArithmMaskTest test; test.safe_run(); }
|
||||||
|
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user