为什么filter2D和conv2的结果如此不同?

时间:2017-10-26 17:36:59

标签: c++ matlab opencv image-processing

我试图使用OpenCV将MATLAB代码翻译成C ++。特别是,我正在尝试翻译以下功能:

function sigma = EstimateNoise(inputImg)
    [h, w]=size(inputImg);
    inputImg = double(inputImg);

    % compute sum of absolute values of Laplacian
    M = [1 -2 1; -2 4 -2; 1 -2 1];
    sigma = sum(sum(abs(conv2(inputImg, M))));

    % scale sigma with proposed coefficients
    sigma = sigma*sqrt(0.5*pi)./(6*(w-2)*(h-2));

end

我的模拟

double EstimateNoise(Mat inputImg) {
    int width = inputImg.cols;
    int height = inputImg.rows;
    // compute sum of absolute values of Laplacian
    char M[9] = {1,-2,1 -2,4,-2, 1,-2,1};
    Mat MatM = Mat(3, 3, CV_8S, M);
    filter2D(inputImg, inputImg, inputImg.depth(), MatM);
    //conv2(inputImg, MatM, CONVOLUTION_FULL, inputImg);
    absdiff(inputImg, Scalar::all(0), inputImg);
    Scalar summa = sum(inputImg);
    double sigma = summa[0];

    // scale sigma with proposed coefficients
    sigma = sigma*sqrt(0.5*M_PI) / (6 * (width - 2)*(height - 2));

    return sigma;

}

但是这些函数的结果差异很大(在C ++中约为3.15,而在~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 我在网络上找到了改进的conv2版本,其中包含其他参数'same''valid',其结果与内置filter2D差别不大。
这个功能本身:

void conv2(const Mat &img, const Mat& kernel, \
    ConvolutionType type, Mat& dest) {
    Mat source = img;
    if (CONVOLUTION_FULL == type) {
        source = Mat();
        const int additionalRows = kernel.rows - 1, additionalCols = kernel.cols - 1;
        copyMakeBorder(img, source, (additionalRows + 1) / 2, additionalRows / 2, \
                       (additionalCols + 1) / 2, additionalCols / 2, \
                        BORDER_CONSTANT, Scalar(0));
    }

    Point anchor(kernel.cols - kernel.cols / 2 - 1, \
                 kernel.rows - kernel.rows / 2 - 1);
    int borderMode = BORDER_CONSTANT;
    flip(kernel, kernel, -1);
    filter2D(source, dest, img.depth(), kernel, anchor, 0, borderMode);

    if (CONVOLUTION_VALID == type) {
        dest = dest.colRange((kernel.cols - 1) / 2, dest.cols - kernel.cols / 2)
            .rowRange((kernel.rows - 1) / 2, dest.rows - kernel.rows / 2);
    }
}

您对获得类似于MATLAB的结果有何建议?

0 个答案:

没有答案