Assertion error on using BoxFilter

Hello Community,

I’ve been using boxFilter and sqrBoxFilter functions of opencv, for the implementation of wiener filter. It worked perfectly fine with openCV 4.2. I needed to upgrade the lib to 4.7. On upgradation, I’m getting assertion error.

My Code:

void WienerFilter(const cv::Mat& src, cv::Mat& dst, double noiseVariance, const cv::Size& block) {

    int h = src.rows;
    int w = src.cols;
    dst = cv::Mat1b(h, w);
    cv::Mat1d means, sqrMeans, variances;
    cv::Mat1d avgVarianceMat;

    cv::boxFilter(src, means, CV_64F, block, cv::Point(-1, -1), false, cv::BORDER_REPLICATE);
   cv::sqrBoxFilter(src, sqrMeans, CV_64F, block, cv::Point(-1, -1), false, cv::BORDER_REPLICATE);

    cv::Mat1d means2 = means.mul(means);
    variances = sqrMeans - (means.mul(means));

    if (noiseVariance < 0) {

        // We have to estimate the noiseVariance
        reduce(variances, avgVarianceMat, 1, cv::REDUCE_SUM, -1);

        reduce(avgVarianceMat, avgVarianceMat, 0, cv::REDUCE_SUM, -1);
        noiseVariance = avgVarianceMat(0, 0) / (h * w);

    }
    for (int r = 0; r < h; ++r) {
        // get row pointers
        uchar const* const srcRow = src.ptr<uchar>(r);
        uchar* const dstRow = dst.ptr<uchar>(r);
        double* const varRow = variances.ptr<double>(r);
        double* const meanRow = means.ptr<double>(r);

        for (int c = 0; c < w; ++c) {

            dstRow[c] = cv::saturate_cast<uchar>(
                        meanRow[c] + max(0., varRow[c] - noiseVariance) / max(varRow[c], noiseVariance) * (srcRow[c] - meanRow[c])

                        );

        }

    }
}

Error obtained:

OpenCV: terminate handler is called! The last OpenCV error is:
OpenCV(4.6.0) Error: Assertion failed (0 <= anchor.x && anchor.x < ksize.width && 0 <= anchor.y && anchor.y < ksize.height) in init, file C:/M/mingw-w64-opencv/src/opencv-4.6.0/modules/imgproc/src/filter.dispatch.cpp, line 145

Can someone please help me with this?

Thanks

I think you must allocate means before called boxfilter
https://docs.opencv.org/4.x/d4/d86/group__imgproc__filter.html#gad533230ebf2d42509547d514f7d3fbc3

Parameters

src input image.
dst output image of the same size and type as src.

dst need not be allocated. all calls do that themselves, by calling a recreate/resize kinda method.

the issue looks like block is invalid.

WienerFilter(cvImage, outputImage,-1,cv::Size(5,5)); → this is how the function is called. Is there any changes required on how the block is mentioned? Thanks

Pix * pix8 = pixConvertTo8(pix, 0);

    cv::Mat mat(cv::Size(pix8->w, pix8->h), CV_8UC1);

    uint32_t *line = pix8->data;

    for (uint32_t y = 0; y < pix8->h; ++y) {

            for (uint32_t x = 0; x < pix8->w; ++x) {

                    mat.at<uchar>(y, x) = GET_DATA_BYTE(line, x);

            }

            line += pix8->wpl;

    }

The input is of type CV_8UC1 , should that be converted to the mentioned depth? Thanks