finally fix cv::subtract

This commit is contained in:
Vladislav Vinogradov 2014-05-08 11:59:30 +04:00
parent 629461c836
commit 77275031ab
2 changed files with 215 additions and 19 deletions

View File

@ -1562,10 +1562,12 @@ void cv::subtract( InputArray _src1, InputArray _src2, OutputArray _dst,
bool src1Scalar = checkScalar(src1, _src2.type(), kind1, kind2);
bool src2Scalar = checkScalar(src2, _src1.type(), kind2, kind1);
if (!src1Scalar && !src2Scalar && mask.empty() &&
src1.depth() == CV_8U && src2.depth() == CV_8U)
if (!src1Scalar && !src2Scalar &&
src1.depth() == CV_8U && src2.type() == src1.type() &&
src1.dims == 2 && src2.size() == src1.size() &&
mask.empty())
{
if (dtype == -1)
if (dtype < 0)
{
if (_dst.fixedType())
{
@ -1577,11 +1579,11 @@ void cv::subtract( InputArray _src1, InputArray _src2, OutputArray _dst,
}
}
dtype = CV_MAKE_TYPE(CV_MAT_DEPTH(dtype), _src1.channels());
dtype = CV_MAT_DEPTH(dtype);
if (dtype == _dst.type())
if (!_dst.fixedType() || dtype == _dst.depth())
{
_dst.create(_src1.size(), dtype);
_dst.create(src1.size(), CV_MAKE_TYPE(dtype, src1.channels()));
if (dtype == CV_16S)
{

View File

@ -1580,21 +1580,215 @@ TEST_P(Mul1, One)
INSTANTIATE_TEST_CASE_P(Arithm, Mul1, testing::Values(Size(2, 2), Size(1, 1)));
TEST(Subtract, EmptyOutputMat)
class SubtractOutputMatNotEmpty : public testing::TestWithParam< std::tr1::tuple<cv::Size, perf::MatType, perf::MatDepth, bool> >
{
cv::Mat src1 = cv::Mat::zeros(16, 16, CV_8UC1);
cv::Mat src2 = cv::Mat::zeros(16, 16, CV_8UC1);
cv::Mat dst1, dst2, dst3;
public:
cv::Size size;
int src_type;
int dst_depth;
bool fixed;
cv::subtract(src1, src2, dst1, cv::noArray(), CV_16S);
cv::subtract(src1, src2, dst2);
cv::subtract(src1, cv::Scalar::all(0), dst3, cv::noArray(), CV_16S);
ASSERT_FALSE(dst1.empty());
ASSERT_FALSE(dst2.empty());
ASSERT_FALSE(dst3.empty());
ASSERT_EQ(0, cv::countNonZero(dst1));
ASSERT_EQ(0, cv::countNonZero(dst2));
ASSERT_EQ(0, cv::countNonZero(dst3));
void SetUp()
{
size = std::tr1::get<0>(GetParam());
src_type = std::tr1::get<1>(GetParam());
dst_depth = std::tr1::get<2>(GetParam());
fixed = std::tr1::get<3>(GetParam());
}
};
TEST_P(SubtractOutputMatNotEmpty, Mat_Mat)
{
cv::Mat src1(size, src_type, cv::Scalar::all(16));
cv::Mat src2(size, src_type, cv::Scalar::all(16));
cv::Mat dst;
if (!fixed)
{
cv::subtract(src1, src2, dst, cv::noArray(), dst_depth);
}
else
{
const cv::Mat fixed_dst(size, CV_MAKE_TYPE((dst_depth > 0 ? dst_depth : CV_16S), src1.channels()));
cv::subtract(src1, src2, fixed_dst, cv::noArray(), dst_depth);
dst = fixed_dst;
dst_depth = fixed_dst.depth();
}
ASSERT_FALSE(dst.empty());
ASSERT_EQ(src1.size(), dst.size());
ASSERT_EQ(dst_depth > 0 ? dst_depth : src1.depth(), dst.depth());
ASSERT_EQ(0, cv::countNonZero(dst.reshape(1)));
}
TEST_P(SubtractOutputMatNotEmpty, Mat_Mat_WithMask)
{
cv::Mat src1(size, src_type, cv::Scalar::all(16));
cv::Mat src2(size, src_type, cv::Scalar::all(16));
cv::Mat mask(size, CV_8UC1, cv::Scalar::all(255));
cv::Mat dst;
if (!fixed)
{
cv::subtract(src1, src2, dst, mask, dst_depth);
}
else
{
const cv::Mat fixed_dst(size, CV_MAKE_TYPE((dst_depth > 0 ? dst_depth : CV_16S), src1.channels()));
cv::subtract(src1, src2, fixed_dst, mask, dst_depth);
dst = fixed_dst;
dst_depth = fixed_dst.depth();
}
ASSERT_FALSE(dst.empty());
ASSERT_EQ(src1.size(), dst.size());
ASSERT_EQ(dst_depth > 0 ? dst_depth : src1.depth(), dst.depth());
ASSERT_EQ(0, cv::countNonZero(dst.reshape(1)));
}
TEST_P(SubtractOutputMatNotEmpty, Mat_Mat_Expr)
{
cv::Mat src1(size, src_type, cv::Scalar::all(16));
cv::Mat src2(size, src_type, cv::Scalar::all(16));
cv::Mat dst = src1 - src2;
ASSERT_FALSE(dst.empty());
ASSERT_EQ(src1.size(), dst.size());
ASSERT_EQ(src1.depth(), dst.depth());
ASSERT_EQ(0, cv::countNonZero(dst.reshape(1)));
}
TEST_P(SubtractOutputMatNotEmpty, Mat_Scalar)
{
cv::Mat src(size, src_type, cv::Scalar::all(16));
cv::Mat dst;
if (!fixed)
{
cv::subtract(src, cv::Scalar::all(16), dst, cv::noArray(), dst_depth);
}
else
{
const cv::Mat fixed_dst(size, CV_MAKE_TYPE((dst_depth > 0 ? dst_depth : CV_16S), src.channels()));
cv::subtract(src, cv::Scalar::all(16), fixed_dst, cv::noArray(), dst_depth);
dst = fixed_dst;
dst_depth = fixed_dst.depth();
}
ASSERT_FALSE(dst.empty());
ASSERT_EQ(src.size(), dst.size());
ASSERT_EQ(dst_depth > 0 ? dst_depth : src.depth(), dst.depth());
ASSERT_EQ(0, cv::countNonZero(dst.reshape(1)));
}
TEST_P(SubtractOutputMatNotEmpty, Mat_Scalar_WithMask)
{
cv::Mat src(size, src_type, cv::Scalar::all(16));
cv::Mat mask(size, CV_8UC1, cv::Scalar::all(255));
cv::Mat dst;
if (!fixed)
{
cv::subtract(src, cv::Scalar::all(16), dst, mask, dst_depth);
}
else
{
const cv::Mat fixed_dst(size, CV_MAKE_TYPE((dst_depth > 0 ? dst_depth : CV_16S), src.channels()));
cv::subtract(src, cv::Scalar::all(16), fixed_dst, mask, dst_depth);
dst = fixed_dst;
dst_depth = fixed_dst.depth();
}
ASSERT_FALSE(dst.empty());
ASSERT_EQ(src.size(), dst.size());
ASSERT_EQ(dst_depth > 0 ? dst_depth : src.depth(), dst.depth());
ASSERT_EQ(0, cv::countNonZero(dst.reshape(1)));
}
TEST_P(SubtractOutputMatNotEmpty, Scalar_Mat)
{
cv::Mat src(size, src_type, cv::Scalar::all(16));
cv::Mat dst;
if (!fixed)
{
cv::subtract(cv::Scalar::all(16), src, dst, cv::noArray(), dst_depth);
}
else
{
const cv::Mat fixed_dst(size, CV_MAKE_TYPE((dst_depth > 0 ? dst_depth : CV_16S), src.channels()));
cv::subtract(cv::Scalar::all(16), src, fixed_dst, cv::noArray(), dst_depth);
dst = fixed_dst;
dst_depth = fixed_dst.depth();
}
ASSERT_FALSE(dst.empty());
ASSERT_EQ(src.size(), dst.size());
ASSERT_EQ(dst_depth > 0 ? dst_depth : src.depth(), dst.depth());
ASSERT_EQ(0, cv::countNonZero(dst.reshape(1)));
}
TEST_P(SubtractOutputMatNotEmpty, Scalar_Mat_WithMask)
{
cv::Mat src(size, src_type, cv::Scalar::all(16));
cv::Mat mask(size, CV_8UC1, cv::Scalar::all(255));
cv::Mat dst;
if (!fixed)
{
cv::subtract(cv::Scalar::all(16), src, dst, mask, dst_depth);
}
else
{
const cv::Mat fixed_dst(size, CV_MAKE_TYPE((dst_depth > 0 ? dst_depth : CV_16S), src.channels()));
cv::subtract(cv::Scalar::all(16), src, fixed_dst, mask, dst_depth);
dst = fixed_dst;
dst_depth = fixed_dst.depth();
}
ASSERT_FALSE(dst.empty());
ASSERT_EQ(src.size(), dst.size());
ASSERT_EQ(dst_depth > 0 ? dst_depth : src.depth(), dst.depth());
ASSERT_EQ(0, cv::countNonZero(dst.reshape(1)));
}
TEST_P(SubtractOutputMatNotEmpty, Mat_Mat_3d)
{
int dims[] = {5, size.height, size.width};
cv::Mat src1(3, dims, src_type, cv::Scalar::all(16));
cv::Mat src2(3, dims, src_type, cv::Scalar::all(16));
cv::Mat dst;
if (!fixed)
{
cv::subtract(src1, src2, dst, cv::noArray(), dst_depth);
}
else
{
const cv::Mat fixed_dst(3, dims, CV_MAKE_TYPE((dst_depth > 0 ? dst_depth : CV_16S), src1.channels()));
cv::subtract(src1, src2, fixed_dst, cv::noArray(), dst_depth);
dst = fixed_dst;
dst_depth = fixed_dst.depth();
}
ASSERT_FALSE(dst.empty());
ASSERT_EQ(src1.dims, dst.dims);
ASSERT_EQ(src1.size, dst.size);
ASSERT_EQ(dst_depth > 0 ? dst_depth : src1.depth(), dst.depth());
ASSERT_EQ(0, cv::countNonZero(dst.reshape(1)));
}
INSTANTIATE_TEST_CASE_P(Arithm, SubtractOutputMatNotEmpty, testing::Combine(
testing::Values(cv::Size(16, 16), cv::Size(13, 13), cv::Size(16, 13), cv::Size(13, 16)),
testing::Values(perf::MatType(CV_8UC1), CV_8UC3, CV_8UC4, CV_16SC1, CV_16SC3),
testing::Values(-1, CV_16S, CV_32S, CV_32F),
testing::Bool()));