imgproc: add src.empty() checks in filter operations

pull/16864/head
Alexander Alekhin 5 years ago
parent 183e4d50ed
commit 0fb4f2cc9c
  1. 2
      modules/imgproc/src/bilateral_filter.dispatch.cpp
  2. 4
      modules/imgproc/src/box_filter.dispatch.cpp
  3. 6
      modules/imgproc/src/deriv.cpp
  4. 15
      modules/imgproc/src/filter.dispatch.cpp
  5. 2
      modules/imgproc/src/median_blur.dispatch.cpp
  6. 8
      modules/imgproc/src/morph.dispatch.cpp
  7. 2
      modules/imgproc/src/smooth.dispatch.cpp
  8. 33
      modules/imgproc/test/test_filter.cpp
  9. 31
      modules/ts/include/opencv2/ts/ts_ext.hpp

@ -406,6 +406,8 @@ void bilateralFilter( InputArray _src, OutputArray _dst, int d,
{
CV_INSTRUMENT_REGION();
CV_Assert(!_src.empty());
_dst.create( _src.size(), _src.type() );
CV_OCL_RUN(_src.dims() <= 2 && _dst.isUMat(),

@ -443,6 +443,8 @@ void boxFilter(InputArray _src, OutputArray _dst, int ddepth,
{
CV_INSTRUMENT_REGION();
CV_Assert(!_src.empty());
CV_OCL_RUN(_dst.isUMat() &&
(borderType == BORDER_REPLICATE || borderType == BORDER_CONSTANT ||
borderType == BORDER_REFLECT || borderType == BORDER_REFLECT_101),
@ -514,6 +516,8 @@ void sqrBoxFilter(InputArray _src, OutputArray _dst, int ddepth,
{
CV_INSTRUMENT_REGION();
CV_Assert(!_src.empty());
int srcType = _src.type(), sdepth = CV_MAT_DEPTH(srcType), cn = CV_MAT_CN(srcType);
Size size = _src.size();

@ -416,6 +416,8 @@ void cv::Sobel( InputArray _src, OutputArray _dst, int ddepth, int dx, int dy,
{
CV_INSTRUMENT_REGION();
CV_Assert(!_src.empty());
int stype = _src.type(), sdepth = CV_MAT_DEPTH(stype), cn = CV_MAT_CN(stype);
if (ddepth < 0)
ddepth = sdepth;
@ -468,6 +470,8 @@ void cv::Scharr( InputArray _src, OutputArray _dst, int ddepth, int dx, int dy,
{
CV_INSTRUMENT_REGION();
CV_Assert(!_src.empty());
int stype = _src.type(), sdepth = CV_MAT_DEPTH(stype), cn = CV_MAT_CN(stype);
if (ddepth < 0)
ddepth = sdepth;
@ -785,6 +789,8 @@ void cv::Laplacian( InputArray _src, OutputArray _dst, int ddepth, int ksize,
{
CV_INSTRUMENT_REGION();
CV_Assert(!_src.empty());
int stype = _src.type(), sdepth = CV_MAT_DEPTH(stype), cn = CV_MAT_CN(stype);
if (ddepth < 0)
ddepth = sdepth;

@ -169,6 +169,9 @@ int FilterEngine::start(const Size& _wholeSize, const Size& sz, const Point& ofs
{
CV_INSTRUMENT_REGION();
CV_Assert(!sz.empty());
CV_Assert(!_wholeSize.empty());
CV_CPU_DISPATCH(FilterEngine__start, (*this, _wholeSize, sz, ofs),
CV_CPU_DISPATCH_MODES_ALL);
}
@ -176,6 +179,11 @@ int FilterEngine::start(const Size& _wholeSize, const Size& sz, const Point& ofs
int FilterEngine::start(const Mat& src, const Size &wsz, const Point &ofs)
{
CV_INSTRUMENT_REGION();
CV_Assert(!src.empty());
CV_Assert(!wsz.empty());
start( wsz, src.size(), ofs);
return startY - ofs.y;
}
@ -1398,6 +1406,9 @@ void filter2D(InputArray _src, OutputArray _dst, int ddepth,
{
CV_INSTRUMENT_REGION();
CV_Assert(!_src.empty());
CV_Assert(!_kernel.empty());
CV_OCL_RUN(_dst.isUMat() && _src.dims() <= 2,
ocl_filter2D(_src, _dst, ddepth, _kernel, anchor0, delta, borderType))
@ -1429,6 +1440,10 @@ void sepFilter2D(InputArray _src, OutputArray _dst, int ddepth,
{
CV_INSTRUMENT_REGION();
CV_Assert(!_src.empty());
CV_Assert(!_kernelX.empty());
CV_Assert(!_kernelY.empty());
CV_OCL_RUN(_dst.isUMat() && _src.dims() <= 2 && (size_t)_src.rows() > _kernelY.total() && (size_t)_src.cols() > _kernelX.total(),
ocl_sepFilter2D(_src, _dst, ddepth, _kernelX, _kernelY, anchor, delta, borderType))

@ -280,6 +280,8 @@ void medianBlur( InputArray _src0, OutputArray _dst, int ksize )
{
CV_INSTRUMENT_REGION();
CV_Assert(!_src0.empty());
CV_Assert( (ksize % 2 == 1) && (_src0.dims() <= 2 ));
if( ksize <= 1 || _src0.empty() )

@ -939,6 +939,8 @@ static void morphOp( int op, InputArray _src, OutputArray _dst,
{
CV_INSTRUMENT_REGION();
CV_Assert(!_src.empty());
Mat kernel = _kernel.getMat();
Size ksize = !kernel.empty() ? kernel.size() : Size(3,3);
anchor = normalizeAnchor(anchor, ksize);
@ -1005,6 +1007,8 @@ void erode( InputArray src, OutputArray dst, InputArray kernel,
{
CV_INSTRUMENT_REGION();
CV_Assert(!src.empty());
morphOp( MORPH_ERODE, src, dst, kernel, anchor, iterations, borderType, borderValue );
}
@ -1015,6 +1019,8 @@ void dilate( InputArray src, OutputArray dst, InputArray kernel,
{
CV_INSTRUMENT_REGION();
CV_Assert(!src.empty());
morphOp( MORPH_DILATE, src, dst, kernel, anchor, iterations, borderType, borderValue );
}
@ -1154,6 +1160,8 @@ void morphologyEx( InputArray _src, OutputArray _dst, int op,
{
CV_INSTRUMENT_REGION();
CV_Assert(!_src.empty());
Mat kernel = _kernel.getMat();
if (kernel.empty())
{

@ -603,6 +603,8 @@ void GaussianBlur(InputArray _src, OutputArray _dst, Size ksize,
{
CV_INSTRUMENT_REGION();
CV_Assert(!_src.empty());
int type = _src.type();
Size size = _src.size();
_dst.create( size, type );

@ -2323,4 +2323,37 @@ TEST(Imgproc_Pyrdown, issue_12961)
ASSERT_EQ(0.0, cv::norm(dst));
}
// https://github.com/opencv/opencv/issues/16857
TEST(Imgproc, filter_empty_src_16857)
{
#define CV_TEST_EXPECT_EMPTY_THROW(statement) CV_TEST_EXPECT_EXCEPTION_MESSAGE(statement, ".empty()")
Mat src, dst, dst2;
CV_TEST_EXPECT_EMPTY_THROW(bilateralFilter(src, dst, 5, 50, 20));
CV_TEST_EXPECT_EMPTY_THROW(blur(src, dst, Size(3, 3)));
CV_TEST_EXPECT_EMPTY_THROW(boxFilter(src, dst, CV_8U, Size(3, 3)));
CV_TEST_EXPECT_EMPTY_THROW(sqrBoxFilter(src, dst, CV_8U, Size(3, 3)));
CV_TEST_EXPECT_EMPTY_THROW(medianBlur(src, dst, 3));
CV_TEST_EXPECT_EMPTY_THROW(GaussianBlur(src, dst, Size(3, 3), 0));
CV_TEST_EXPECT_EMPTY_THROW(cv::filter2D(src, dst, CV_8U, Mat_<float>::zeros(Size(3, 3))));
CV_TEST_EXPECT_EMPTY_THROW(sepFilter2D(src, dst, CV_8U, Mat_<float>::zeros(Size(3, 1)), Mat_<float>::zeros(Size(1, 3))));
CV_TEST_EXPECT_EMPTY_THROW(Sobel(src, dst, CV_8U, 1, 1));
CV_TEST_EXPECT_EMPTY_THROW(spatialGradient(src, dst, dst2));
CV_TEST_EXPECT_EMPTY_THROW(Scharr(src, dst, CV_8U, 1, 1));
CV_TEST_EXPECT_EMPTY_THROW(Laplacian(src, dst, CV_8U));
CV_TEST_EXPECT_EMPTY_THROW(cv::dilate(src, dst, Mat())); // cvtest:: by default
CV_TEST_EXPECT_EMPTY_THROW(cv::erode(src, dst, Mat())); // cvtest:: by default
CV_TEST_EXPECT_EMPTY_THROW(morphologyEx(src, dst, MORPH_OPEN, Mat()));
//debug: CV_TEST_EXPECT_EMPTY_THROW(blur(Mat_<uchar>(Size(3,3)), dst, Size(3, 3)));
EXPECT_TRUE(src.empty());
EXPECT_TRUE(dst.empty());
EXPECT_TRUE(dst2.empty());
}
}} // namespace

@ -161,4 +161,35 @@ bool checkBigDataTests();
#undef TEST_P
#define TEST_P(test_case_name, test_name) CV__TEST_P(test_case_name, test_name, Body, CV__TEST_BODY_IMPL)
#define CV_TEST_EXPECT_EXCEPTION_MESSAGE(statement, msg) \
GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
if (::testing::internal::AlwaysTrue()) { \
const char* msg_ = msg; \
bool hasException = false; \
try { \
GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \
} \
catch (const cv::Exception& e) { \
if (NULL == strstr(e.what(), msg_)) \
ADD_FAILURE() << "Unexpected cv::Exception is raised: " << #statement << "\n Expected message substring: '" << msg_ << "'. Actual message:\n" << e.what(); \
hasException = true; \
} \
catch (const std::exception& e) { \
ADD_FAILURE() << "Unexpected std::exception is raised: " << #statement << "\n" << e.what(); \
hasException = true; \
} \
catch (...) { \
ADD_FAILURE() << "Unexpected C++ exception is raised: " << #statement; \
hasException = true; \
} \
if (!hasException) { \
goto GTEST_CONCAT_TOKEN_(gtest_label_test_, __LINE__); \
} \
} else \
GTEST_CONCAT_TOKEN_(gtest_label_test_, __LINE__): \
ADD_FAILURE() << "Failed: Expected: " #statement " throws an '" << msg << "' exception.\n" \
" Actual: it doesn't."
#endif // OPENCV_TS_EXT_HPP

Loading…
Cancel
Save