From 11ddb9332c2b2a2bb1e27f7669e11cc5ccdab937 Mon Sep 17 00:00:00 2001 From: elenagvo Date: Thu, 23 Nov 2017 11:40:54 +0300 Subject: [PATCH 1/4] add HAL for adaptiveThreshold --- modules/imgproc/include/opencv2/imgproc.hpp | 3 ++- modules/imgproc/perf/perf_threshold.cpp | 15 +++++++++------ modules/imgproc/src/hal_replacement.hpp | 17 +++++++++++++++++ modules/imgproc/src/thresh.cpp | 5 ++++- 4 files changed, 32 insertions(+), 8 deletions(-) diff --git a/modules/imgproc/include/opencv2/imgproc.hpp b/modules/imgproc/include/opencv2/imgproc.hpp index cdc55a3c9e..06f333cd0c 100644 --- a/modules/imgproc/include/opencv2/imgproc.hpp +++ b/modules/imgproc/include/opencv2/imgproc.hpp @@ -2805,7 +2805,8 @@ The function can process the image in-place. @param src Source 8-bit single-channel image. @param dst Destination image of the same size and the same type as src. @param maxValue Non-zero value assigned to the pixels for which the condition is satisfied -@param adaptiveMethod Adaptive thresholding algorithm to use, see cv::AdaptiveThresholdTypes +@param adaptiveMethod Adaptive thresholding algorithm to use, see cv::AdaptiveThresholdTypes. +The BORDER_REPLICATE | BORDER_ISOLATED is used to process boundaries. @param thresholdType Thresholding type that must be either THRESH_BINARY or THRESH_BINARY_INV, see cv::ThresholdTypes. @param blockSize Size of a pixel neighborhood that is used to calculate a threshold value for the diff --git a/modules/imgproc/perf/perf_threshold.cpp b/modules/imgproc/perf/perf_threshold.cpp index 846f1a0290..bbe151dac9 100644 --- a/modules/imgproc/perf/perf_threshold.cpp +++ b/modules/imgproc/perf/perf_threshold.cpp @@ -60,15 +60,16 @@ PERF_TEST_P(Size_Only, threshold_otsu, testing::Values(TYPICAL_MAT_SIZES)) CV_ENUM(AdaptThreshType, THRESH_BINARY, THRESH_BINARY_INV) CV_ENUM(AdaptThreshMethod, ADAPTIVE_THRESH_MEAN_C, ADAPTIVE_THRESH_GAUSSIAN_C) -typedef std::tr1::tuple Size_AdaptThreshType_AdaptThreshMethod_BlockSize_t; -typedef perf::TestBaseWithParam Size_AdaptThreshType_AdaptThreshMethod_BlockSize; +typedef std::tr1::tuple Size_AdaptThreshType_AdaptThreshMethod_BlockSize_Delta_t; +typedef perf::TestBaseWithParam Size_AdaptThreshType_AdaptThreshMethod_BlockSize_Delta; -PERF_TEST_P(Size_AdaptThreshType_AdaptThreshMethod_BlockSize, adaptiveThreshold, +PERF_TEST_P(Size_AdaptThreshType_AdaptThreshMethod_BlockSize_Delta, adaptiveThreshold, testing::Combine( testing::Values(TYPICAL_MAT_SIZES), AdaptThreshType::all(), AdaptThreshMethod::all(), - testing::Values(3, 5) + testing::Values(3, 5), + testing::Values(0.0, 10.0) ) ) { @@ -76,12 +77,14 @@ PERF_TEST_P(Size_AdaptThreshType_AdaptThreshMethod_BlockSize, adaptiveThreshold, AdaptThreshType adaptThreshType = get<1>(GetParam()); AdaptThreshMethod adaptThreshMethod = get<2>(GetParam()); int blockSize = get<3>(GetParam()); + double C = get<4>(GetParam()); double maxValue = theRNG().uniform(1, 254); - double C = 10.0; int type = CV_8UC1; - Mat src(sz, type); + + Mat src_full(cv::Size(sz.width + 2, sz.height + 2), type); + Mat src = src_full(cv::Rect(1, 1, sz.width, sz.height)); Mat dst(sz, type); declare.in(src, WARMUP_RNG).out(dst); diff --git a/modules/imgproc/src/hal_replacement.hpp b/modules/imgproc/src/hal_replacement.hpp index f43fc70ee0..d838d68466 100644 --- a/modules/imgproc/src/hal_replacement.hpp +++ b/modules/imgproc/src/hal_replacement.hpp @@ -630,6 +630,23 @@ inline int hal_ni_medianBlur(const uchar* src_data, size_t src_step, uchar* dst_ #define cv_hal_medianBlur hal_ni_medianBlur //! @endcond +/** + @brief Calculates adaptive threshold + @param src_data,src_step Source image + @param dst_data,dst_step Destination image + @param width,height Source image dimensions + @param maxValue Value assigned to the pixels for which the condition is satisfied + @param adaptiveMethod Adaptive thresholding algorithm + @param thresholdType Thresholding type + @param blockSize Size of a pixel neighborhood that is used to calculate a threshold value + @param C Constant subtracted from the mean or weighted mean +*/ +inline int hal_ni_adaptiveThreshold(const uchar* src_data, size_t src_step, uchar* dst_data, size_t dst_step, int width, int height, double maxValue, int adaptiveMethod, int thresholdType, int blockSize, double C) { return CV_HAL_ERROR_NOT_IMPLEMENTED; } + +//! @cond IGNORED +#define cv_hal_adaptiveThreshold hal_ni_adaptiveThreshold +//! @endcond + //! @} #if defined __GNUC__ diff --git a/modules/imgproc/src/thresh.cpp b/modules/imgproc/src/thresh.cpp index f7ad1955a8..a428f7c0e3 100644 --- a/modules/imgproc/src/thresh.cpp +++ b/modules/imgproc/src/thresh.cpp @@ -1530,6 +1530,9 @@ void cv::adaptiveThreshold( InputArray _src, OutputArray _dst, double maxValue, return; } + CALL_HAL(adaptiveThreshold, cv_hal_adaptiveThreshold, src.data, src.step, dst.data, dst.step, src.cols, src.rows, + maxValue, method, type, blockSize, delta); + Mat mean; if( src.data != dst.data ) @@ -1537,7 +1540,7 @@ void cv::adaptiveThreshold( InputArray _src, OutputArray _dst, double maxValue, if (method == ADAPTIVE_THRESH_MEAN_C) boxFilter( src, mean, src.type(), Size(blockSize, blockSize), - Point(-1,-1), true, BORDER_REPLICATE ); + Point(-1,-1), true, BORDER_REPLICATE|BORDER_ISOLATED ); else if (method == ADAPTIVE_THRESH_GAUSSIAN_C) { Mat srcfloat,meanfloat; From c95bc0c7fdeabcd7287722fd6bb743ac4e748dbc Mon Sep 17 00:00:00 2001 From: elenagvo Date: Mon, 27 Nov 2017 15:11:19 +0300 Subject: [PATCH 2/4] add HAL for threshold --- modules/imgproc/src/hal_replacement.hpp | 15 +++++++++++++++ modules/imgproc/src/thresh.cpp | 3 +++ 2 files changed, 18 insertions(+) diff --git a/modules/imgproc/src/hal_replacement.hpp b/modules/imgproc/src/hal_replacement.hpp index d838d68466..b5855661bd 100644 --- a/modules/imgproc/src/hal_replacement.hpp +++ b/modules/imgproc/src/hal_replacement.hpp @@ -647,6 +647,21 @@ inline int hal_ni_adaptiveThreshold(const uchar* src_data, size_t src_step, ucha #define cv_hal_adaptiveThreshold hal_ni_adaptiveThreshold //! @endcond +/** + @brief Calculates fixed-level threshold to each array element + @param src_data,src_step Source image + @param dst_data,dst_step Destination image + @param width,height Source image dimensions + @param thresh Threshold value + @param maxValue Value assigned to the pixels for which the condition is satisfied + @param thresholdType Thresholding type +*/ +inline int hal_ni_thresholdBin8u(const uchar* src_data, size_t src_step, uchar* dst_data, size_t dst_step, int width, int height, double thresh, double maxValue, int thresholdType) { return CV_HAL_ERROR_NOT_IMPLEMENTED; } + +//! @cond IGNORED +#define cv_hal_thresholdBin8u hal_ni_thresholdBin8u +//! @endcond + //! @} #if defined __GNUC__ diff --git a/modules/imgproc/src/thresh.cpp b/modules/imgproc/src/thresh.cpp index a428f7c0e3..5a802b915f 100644 --- a/modules/imgproc/src/thresh.cpp +++ b/modules/imgproc/src/thresh.cpp @@ -141,6 +141,9 @@ thresh_8u( const Mat& _src, Mat& _dst, uchar thresh, uchar maxval, int type ) return; #endif + CALL_HAL(thresholdBin, cv_hal_thresholdBin8u, _src.data, src_step, _dst.data, dst_step, roi.width, roi.height, + thresh, maxval, type); + #if defined(HAVE_IPP) CV_IPP_CHECK() { From 762138e77e25905c804dd958073ee8abc1bf2538 Mon Sep 17 00:00:00 2001 From: elenagvo Date: Tue, 28 Nov 2017 15:55:58 +0300 Subject: [PATCH 3/4] define adaptiveMethod and thresholdType for HAL --- .../include/opencv2/imgproc/hal/interface.h | 20 +++++++++++++++++++ modules/imgproc/src/thresh.cpp | 2 +- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/modules/imgproc/include/opencv2/imgproc/hal/interface.h b/modules/imgproc/include/opencv2/imgproc/hal/interface.h index 23eb0baa40..f8dbcfe791 100644 --- a/modules/imgproc/include/opencv2/imgproc/hal/interface.h +++ b/modules/imgproc/include/opencv2/imgproc/hal/interface.h @@ -21,6 +21,26 @@ #define CV_HAL_MORPH_DILATE 1 //! @} +//! @name Threshold types +//! @sa cv::ThresholdTypes +//! @{ +#define CV_HAL_THRESH_BINARY 0 +#define CV_HAL_THRESH_BINARY_INV 1 +#define CV_HAL_THRESH_TRUNC 2 +#define CV_HAL_THRESH_TOZERO 3 +#define CV_HAL_THRESH_TOZERO_INV 4 +#define CV_HAL_THRESH_MASK 7 +#define CV_HAL_THRESH_OTSU 8 +#define CV_HAL_THRESH_TRIANGLE 16 +//! @} + +//! @name Adaptive threshold algorithm +//! @sa cv::AdaptiveThresholdTypes +//! @{ +#define CV_HAL_ADAPTIVE_THRESH_MEAN_C 0 +#define CV_HAL_ADAPTIVE_THRESH_GAUSSIAN_C 1 +//! @} + //! @} #endif diff --git a/modules/imgproc/src/thresh.cpp b/modules/imgproc/src/thresh.cpp index 5a802b915f..b87f48e67c 100644 --- a/modules/imgproc/src/thresh.cpp +++ b/modules/imgproc/src/thresh.cpp @@ -1549,7 +1549,7 @@ void cv::adaptiveThreshold( InputArray _src, OutputArray _dst, double maxValue, Mat srcfloat,meanfloat; src.convertTo(srcfloat,CV_32F); meanfloat=srcfloat; - GaussianBlur(srcfloat, meanfloat, Size(blockSize, blockSize), 0, 0, BORDER_REPLICATE); + GaussianBlur(srcfloat, meanfloat, Size(blockSize, blockSize), 0, 0, BORDER_REPLICATE|BORDER_ISOLATED); meanfloat.convertTo(mean, src.type()); } else From 73ac5321f503f632763957a3153d8990136636b2 Mon Sep 17 00:00:00 2001 From: elenagvo Date: Tue, 28 Nov 2017 17:42:29 +0300 Subject: [PATCH 4/4] fix threshold HAL --- modules/imgproc/src/hal_replacement.hpp | 6 ++++-- modules/imgproc/src/thresh.cpp | 7 ++++--- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/modules/imgproc/src/hal_replacement.hpp b/modules/imgproc/src/hal_replacement.hpp index b5855661bd..be05644067 100644 --- a/modules/imgproc/src/hal_replacement.hpp +++ b/modules/imgproc/src/hal_replacement.hpp @@ -652,14 +652,16 @@ inline int hal_ni_adaptiveThreshold(const uchar* src_data, size_t src_step, ucha @param src_data,src_step Source image @param dst_data,dst_step Destination image @param width,height Source image dimensions + @param depth Depths of source and destination image + @param cn Number of channels @param thresh Threshold value @param maxValue Value assigned to the pixels for which the condition is satisfied @param thresholdType Thresholding type */ -inline int hal_ni_thresholdBin8u(const uchar* src_data, size_t src_step, uchar* dst_data, size_t dst_step, int width, int height, double thresh, double maxValue, int thresholdType) { return CV_HAL_ERROR_NOT_IMPLEMENTED; } +inline int hal_ni_threshold(const uchar* src_data, size_t src_step, uchar* dst_data, size_t dst_step, int width, int height, int depth, int cn, double thresh, double maxValue, int thresholdType) { return CV_HAL_ERROR_NOT_IMPLEMENTED; } //! @cond IGNORED -#define cv_hal_thresholdBin8u hal_ni_thresholdBin8u +#define cv_hal_threshold hal_ni_threshold //! @endcond //! @} diff --git a/modules/imgproc/src/thresh.cpp b/modules/imgproc/src/thresh.cpp index b87f48e67c..8cf17aebb1 100644 --- a/modules/imgproc/src/thresh.cpp +++ b/modules/imgproc/src/thresh.cpp @@ -141,9 +141,6 @@ thresh_8u( const Mat& _src, Mat& _dst, uchar thresh, uchar maxval, int type ) return; #endif - CALL_HAL(thresholdBin, cv_hal_thresholdBin8u, _src.data, src_step, _dst.data, dst_step, roi.width, roi.height, - thresh, maxval, type); - #if defined(HAVE_IPP) CV_IPP_CHECK() { @@ -1217,6 +1214,10 @@ public: Mat srcStripe = src.rowRange(row0, row1); Mat dstStripe = dst.rowRange(row0, row1); + CALL_HAL(threshold, cv_hal_threshold, srcStripe.data, srcStripe.step, dstStripe.data, dstStripe.step, + srcStripe.cols, srcStripe.rows, srcStripe.depth(), srcStripe.channels(), + thresh, maxval, thresholdType); + if (srcStripe.depth() == CV_8U) { thresh_8u( srcStripe, dstStripe, (uchar)thresh, (uchar)maxval, thresholdType );