diff --git a/modules/ximgproc/include/opencv2/ximgproc/weighted_median_filter.hpp b/modules/ximgproc/include/opencv2/ximgproc/weighted_median_filter.hpp index 30a169cd8..d3da29efd 100644 --- a/modules/ximgproc/include/opencv2/ximgproc/weighted_median_filter.hpp +++ b/modules/ximgproc/include/opencv2/ximgproc/weighted_median_filter.hpp @@ -63,12 +63,12 @@ namespace ximgproc */ enum WMFWeightType { - WMF_EXP, //!< \f$exp(-|I1-I2|^2/(2*sigma^2))\f$ - WMF_IV1, //!< \f$(|I1-I2|+sigma)^-1\f$ - WMF_IV2, //!< \f$(|I1-I2|^2+sigma^2)^-1\f$ - WMF_COS, //!< \f$dot(I1,I2)/(|I1|*|I2|)\f$ - WMF_JAC, //!< \f$(min(r1,r2)+min(g1,g2)+min(b1,b2))/(max(r1,r2)+max(g1,g2)+max(b1,b2))\f$ - WMF_OFF //!< unweighted + WMF_EXP = 1 , //!< \f$exp(-|I1-I2|^2/(2*sigma^2))\f$ + WMF_IV1 = 1 << 1, //!< \f$(|I1-I2|+sigma)^-1\f$ + WMF_IV2 = 1 << 2, //!< \f$(|I1-I2|^2+sigma^2)^-1\f$ + WMF_COS = 1 << 3, //!< \f$dot(I1,I2)/(|I1|*|I2|)\f$ + WMF_JAC = 1 << 4, //!< \f$(min(r1,r2)+min(g1,g2)+min(b1,b2))/(max(r1,r2)+max(g1,g2)+max(b1,b2))\f$ + WMF_OFF = 1 << 5 //!< unweighted }; /** @@ -87,7 +87,8 @@ enum WMFWeightType * * @sa medianBlur, jointBilateralFilter */ -CV_EXPORTS void weightedMedianFilter(InputArray joint, InputArray src, OutputArray dst, int r, double sigma=25.5, WMFWeightType weightType=WMF_EXP, Mat mask=Mat()); +CV_EXPORTS_W void weightedMedianFilter(InputArray joint, InputArray src, OutputArray dst, + int r, double sigma = 25.5, int weightType = WMF_EXP, InputArray mask = noArray()); } } diff --git a/modules/ximgproc/src/weighted_median_filter.cpp b/modules/ximgproc/src/weighted_median_filter.cpp index 358959cdd..d438fb962 100644 --- a/modules/ximgproc/src/weighted_median_filter.cpp +++ b/modules/ximgproc/src/weighted_median_filter.cpp @@ -231,7 +231,7 @@ inline void updateBCB(int &num,int *f,int *b,int i,int v) * If F is 3-channel, perform k-means clustering * If F is 1-channel, only perform type-casting ***************************************************************/ -void featureIndexing(Mat &F, float **&wMap, int &nF, float sigmaI, WMFWeightType weightType){ +void featureIndexing(Mat &F, float **&wMap, int &nF, float sigmaI, int weightType){ // Configuration and Declaration Mat FNew; int cols = F.cols, rows = F.rows; @@ -493,7 +493,7 @@ Mat filterCore(Mat &I, Mat &F, float **wMap, int r=20, int nF=256, int nI=256, M // Move cut-point to the left if(balanceWeight >= 0) { - for(;balanceWeight >= 0 && curMedianVal; curMedianVal--) + for(;balanceWeight >= 0 && curMedianVal > 0; curMedianVal--) { float curWeight = 0; int *nextHist = H[curMedianVal]; @@ -539,8 +539,13 @@ Mat filterCore(Mat &I, Mat &F, float **wMap, int r=20, int nF=256, int nI=256, M } // Weighted median is found and written to the output image - if(balanceWeight<0)outImg.ptr(y,x)[0] = curMedianVal+1; - else outImg.ptr(y,x)[0] = curMedianVal; + if(curMedianVal != -1) + { + if(balanceWeight < 0) + outImg.ptr(y,x)[0] = curMedianVal+1; + else + outImg.ptr(y,x)[0] = curMedianVal; + } // Update joint-histogram and BCB when local window is shifted. int fval,gval,*curHist; @@ -636,7 +641,7 @@ namespace cv { namespace ximgproc { -void weightedMedianFilter(InputArray joint, InputArray src, OutputArray dst, int r, double sigma, WMFWeightType weightType, Mat mask) +void weightedMedianFilter(InputArray joint, InputArray src, OutputArray dst, int r, double sigma, int weightType, InputArray mask) { CV_Assert(!src.empty()); CV_Assert(r > 0 && sigma > 0); @@ -697,7 +702,7 @@ void weightedMedianFilter(InputArray joint, InputArray src, OutputArray dst, int //Filtering - Joint-Histogram Framework for(int i=0; i<(int)Is.size(); i++) { - Is[i] = filterCore(Is[i], F, wMap, r, nF,nI,mask); + Is[i] = filterCore(Is[i], F, wMap, r, nF, nI, mask.getMat()); } float2D_release(wMap); diff --git a/modules/ximgproc/test/test_weighted_median_filter.cpp b/modules/ximgproc/test/test_weighted_median_filter.cpp index 9dea51fd1..69a653047 100644 --- a/modules/ximgproc/test/test_weighted_median_filter.cpp +++ b/modules/ximgproc/test/test_weighted_median_filter.cpp @@ -102,6 +102,16 @@ TEST(WeightedMedianFilterTest, ReferenceAccuracy) EXPECT_LE(cvtest::norm(res, ref, NORM_L2), totalMaxError); } +TEST(WeightedMedianFilterTest, mask_zeros_no_crash) +{ + Mat img = imread(getDataDir() + "cv/ximgproc/sources/01.png"); + Mat mask = Mat::zeros(img.size(), CV_8U); + Mat filtered; + weightedMedianFilter(img, img, filtered, 3, 20, WMF_EXP, mask); + + EXPECT_EQ(cv::norm(img, filtered, NORM_INF), 0.0); +} + INSTANTIATE_TEST_CASE_P(TypicalSET, WeightedMedianFilterTest, Combine(Values(szODD, szQVGA), Values(WMF_EXP, WMF_IV2, WMF_OFF))); }