opencv Sobel算子是否计算相关性?

时间:2017-02-04 06:00:46

标签: c++ opencv image-processing sobel

opencv Sobel算子是否计算相关性,而不是卷积? 我知道filter2D函数计算相关性,我刚刚发现(基于代码的结果)Sobel算子也计算相关性。这是预期的吗?我错过了什么吗?

href

2 个答案:

答案 0 :(得分:0)

修改

要获取OpenCV Sobel内核,您可以调用cv::getDerivKernels来获取两个可分离的内核(let d = Dining.make(blah blah) as! Dining 实际上是在cv::sepFilter2D或英特尔的OpenCV代码中调用的IPP Sobel或任何其他后端(如果存在)并且确实执行了相关性。

下面提到的内核已经过时,但测试代码仍然有用!

最好的选择是测试以避免意外:

cv::Sobel

输出:

{
    cv::RNG(0); //fix RNG

    cv::Mat img(8, 8, CV_8U);
    cv::randu(img, 0, 256);

    cv::Mat sobel_x;
    cv::Sobel(img, sobel_x, CV_64F, 1, 0);

    cv::Mat sobel_filter;
    cv::Mat kern = (cv::Mat_<double>(3, 3) << 1, 0, -1,
                                              2, 0, -2,
                                              1, 0, -1);
    cv::filter2D(img, sobel_filter, CV_64F, kern);

    cv::Mat kern_flip, sobel_filter_conv;
    cv::flip(kern, kern_flip, -1);
    cv::filter2D(img, sobel_filter_conv, CV_64F, kern_flip);

    std::cout << "img:\n" << img << std::endl;
    std::cout << "sobel_x:\n" << sobel_x << std::endl;
    std::cout << "sobel_filter:\n" << sobel_filter << std::endl;
    std::cout << "sobel_filter_conv:\n" << sobel_filter_conv << std::endl;

    cv::Mat diff = sobel_x - sobel_filter;
    cv::Mat diff2 = sobel_x - sobel_filter_conv;
    std::cout << "Diff sobel_x - sobel_filter: " << cv::sum( diff )[0] << std::endl;
    std::cout << "Diff sobel_x - sobel_filter_conv: " << cv::sum( diff2 )[0] << std::endl;
}


{
    cv::RNG(0); //fix RNG

    cv::Mat img(8, 8, CV_8U);
    cv::randu(img, 0, 256);

    cv::Mat sobel_y;
    cv::Sobel(img, sobel_y, CV_64F, 0, 1);

    cv::Mat sobel_filter;
    cv::Mat kern = (cv::Mat_<double>(3, 3) << 1,  2,  1,
                                              0,  0,  0,
                                             -1, -2, -1);
    cv::filter2D(img, sobel_filter, CV_64F, kern);

    cv::Mat kern_flip, sobel_filter_conv;
    cv::flip(kern, kern_flip, -1);
    cv::filter2D(img, sobel_filter_conv, CV_64F, kern_flip);

    std::cout << "img:\n" << img << std::endl;
    std::cout << "sobel_y:\n" << sobel_y << std::endl;
    std::cout << "sobel_filter:\n" << sobel_filter << std::endl;
    std::cout << "sobel_filter_conv:\n" << sobel_filter_conv << std::endl;

    cv::Mat diff = sobel_y - sobel_filter;
    cv::Mat diff2 = sobel_y - sobel_filter_conv;
    std::cout << "Diff sobel_y - sobel_filter: " << cv::sum( diff )[0] << std::endl;
    std::cout << "Diff sobel_y - sobel_filter_conv: " << cv::sum( diff2 )[0] << std::endl;
}

答案 1 :(得分:0)

这是我写的测试,输出说实话。 cv :: Sobel计算相关性而不是卷积。 我使用了以下内核,它与cv :: Sobel

使用的内核相同
kern = [-1, 0, 1;
        -2, 0, 2;
        -1, 0, 1]

结果表明sobelx和filter2d(相关)的输出是相同的。

void test_sobel(){
cv::RNG(0);
cv::Mat src(4,4, CV_8U);
cv::randu(src, 0, 256);
cv::Mat sobelx, dest_corr,dest_conv;
cv::Sobel(src, sobelx, CV_32F,1,0,3);
// sobel uses a 3x3 filter shown as below
Mat kern = (Mat_<float>(3,3)<<-1,0,1,-2,0,2,-1,0,1);
// filter2D computes correlation
cv::filter2D(src,dest_corr,CV_32F,kern);

//flip the kernel in x and y direction for convolution
cv::Mat kern_conv;
cv::flip(kern,kern_conv, -1);
cv::filter2D(src,dest_conv,CV_32F,kern_conv);

std::cout << "kern = \n" << kern<< std::endl;
std::cout << "kern_conv = \n" << kern_conv<< std::endl;
std::cout << "src = \n" << src << std::endl;
std::cout << "sobelx = \n" << sobelx<< std::endl;
std::cout << "dest_corr = \n" << dest_corr<< std::endl;
std::cout << "dest_conv =\n" << dest_conv << std::endl;
cv::Mat diff1 = sobelx - dest_corr;
cv::Mat diff2 = sobelx - dest_conv;
std::cout << "sobelx - dest_corr = " << cv::sum( diff1 )[0] << std::endl;
std::cout << "sobelx - dest_conv = " << cv::sum( diff2 )[0] << std::endl;
}

输出:

kern = 
[-1, 0, 1;
 -2, 0, 2;
-1, 0, 1]
kern_conv = 
[1, 0, -1;
 2, 0, -2;
 1, 0, -1]
src = 
[246, 156, 192,   7;
 165, 166,   2, 179;
 231, 212, 171, 230;
  93, 138, 123,  80]
sobelx = 
[0, -434, -272, 0;
 0, -440, -105, 0;
 0, -253, -9, 0;
 0, -60, -80, 0]
dest_corr = 
[0, -434, -272, 0;
 0, -440, -105, 0;
 0, -253, -9, 0;
 0, -60, -80, 0]
dest_conv =
[0, 434, 272, 0;
 0, 440, 105, 0;
 0, 253, 9, 0;
 0, 60, 80, 0]
sobelx - dest_corr = 0
sobelx - dest_conv = -3306