Search code examples
c++opencvimage-processingsobel

Does opencv Sobel operator compute correlation?


Does opencv Sobel operator compute correlation, not the convolution? I know that the filter2D function computes correlation and i just found out (based from the results of the code)that the Sobel operator also computes correlation. Is this expected? AM i missing something here?

Mat sobelx, dest1,dest2;
Sobel(src, sobelx, src.depth(),1,0,3);
imshow("Sobel filtered in x dir" ,sobelx);
Mat kern = (Mat_<float>(3,3)<<-1,0,1,-1,0,1,-1,0,1);
filter2D(src,dest1,src.type(),kern);
imshow("Sobel in x-dir using corr ", dest1);
/* dest1 equals sobelx  */
flip(kern,kern, -1);//flip the kernel in x and y direction for convolution
filter2D(src,dest2,src.type(),kern);
imshow("Sobel in x-dir using conv ",dest2,);

Solution

  • Here is the test that i wrote and the output tells the truth. cv::Sobel computes correlation and not convolution. I have used the following kernel which is the same as used by cv::Sobel

    kern = [-1, 0, 1;
            -2, 0, 2;
            -1, 0, 1]
    

    The results show that the output of sobelx and filter2d(correlation) is same.

    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;
    }
    

    Output:

    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