What are the kernel coefficients for the OpenCV Sobel filter for sizes larger than 3 x 3?

I am using a 5x5 and 7x7 OpenCV Sobel filter to compute the derived image.

Can someone please let me know the kernel values ​​for the 5x5 and 7x7 Sobel filter in OpenCV? When you google it it shows me many different cores.

Here are some examples for 5 x 5:

1. Separable

2   1   0   -1  -2
4   8   0   -4  -8
6  12   0   -12 -6
4   8   0   -4  -8
2   1   0   -1  -2

      

2. Inseparable

2   1   0   -1  -2
4  10   0   -4  -10
7  17   0   -17 -7
4  10   0   -4  -10
2   1   0   -1  -2

      

3. Strange inseparable

2   1   0   -1  -2
3   2   0   -2  -3
4   3   0   -3  -4
3   2   0   -2  -3
2   1   0   -1  -2

      

+3


source to share


2 answers


You can use getDerivKernels

to define kernel coefficients for the Sobel filter if you really want to see what OpenCV is using. What you need to do is indicate which direction you want and the size of the mask you want. So there are two directions for kernel size, so we need to call this four times.

However, horizontal, x

and vertical, y

1D kernels are returned , which represent a Sobel filter that you can use to perform split 2D filtering through sepFilter2D

. If you really want to see the cores themselves, you just take the external product between the cores x

and y

that come back from getDerivKernels

.

Here's something quick, using the Python OpenCV interface to display 5 x 5 x

, y

and 7 x 7 kernels x

and y

:

In [1]: import numpy as np

In [2]: import cv2

In [3]: sobel5x = cv2.getDerivKernels(1, 0, 5)

In [4]: np.outer(sobel5x[0], sobel5x[1])
Out[4]: 
array([[ -1.,  -4.,  -6.,  -4.,  -1.],
       [ -2.,  -8., -12.,  -8.,  -2.],
       [  0.,   0.,   0.,   0.,   0.],
       [  2.,   8.,  12.,   8.,   2.],
       [  1.,   4.,   6.,   4.,   1.]], dtype=float32)

In [5]: sobel5y = cv2.getDerivKernels(0, 1, 5)

In [6]: np.outer(sobel5y[0], sobel5y[1])
Out[6]: 
array([[ -1.,  -2.,   0.,   2.,   1.],
       [ -4.,  -8.,   0.,   8.,   4.],
       [ -6., -12.,   0.,  12.,   6.],
       [ -4.,  -8.,   0.,   8.,   4.],
       [ -1.,  -2.,   0.,   2.,   1.]], dtype=float32)

In [7]: sobel7x = cv2.getDerivKernels(1, 0, 7)

In [8]: np.outer(sobel7x[0], sobel7x[1])
Out[8]: 
array([[  -1.,   -6.,  -15.,  -20.,  -15.,   -6.,   -1.],
       [  -4.,  -24.,  -60.,  -80.,  -60.,  -24.,   -4.],
       [  -5.,  -30.,  -75., -100.,  -75.,  -30.,   -5.],
       [   0.,    0.,    0.,    0.,    0.,    0.,    0.],
       [   5.,   30.,   75.,  100.,   75.,   30.,    5.],
       [   4.,   24.,   60.,   80.,   60.,   24.,    4.],
       [   1.,    6.,   15.,   20.,   15.,    6.,    1.]], dtype=float32)

In [9]: sobel7y = cv2.getDerivKernels(0, 1, 7)

In [10]: np.outer(sobel7y[0], sobel7y[1])
Out[10]: 
array([[  -1.,   -4.,   -5.,    0.,    5.,    4.,    1.],
       [  -6.,  -24.,  -30.,    0.,   30.,   24.,    6.],
       [ -15.,  -60.,  -75.,    0.,   75.,   60.,   15.],
       [ -20.,  -80., -100.,    0.,  100.,   80.,   20.],
       [ -15.,  -60.,  -75.,    0.,   75.,   60.,   15.],
       [  -6.,  -24.,  -30.,    0.,   30.,   24.,    6.],
       [  -1.,   -4.,   -5.,    0.,    5.,    4.,    1.]], dtype=float32)

      

Please note that the kernels are not normalized . If you want to use them for filtering, you should probably normalize the kernels. There's a flag getDerivKernels

that will allow you to normalize the mask.

Also note that one mask for a given size is a transposition of another, which makes sense if you want to detect edges for a specific orientation.




For completeness, here's the C ++ version of the above Python code. To compile your code, put it in a file ... name it test.cpp

, then do it in a terminal:

g++ -Wall -g -o test test.cpp `pkg-config --cflags --libs opencv`

      

Once compiled, run the program using ./test

.




#include <cv.h>

using namespace std;
using namespace cv;

int main() {

    // For the kernels
    Mat sobelX, sobelY;

    // 5 x 5 - x direction
    getDerivKernels(sobelX, sobelY, 1, 0, 5, false, CV_32F);
    cout << "sobel5x = " << endl << " " << sobelX*sobelY.t() << endl << endl;

    // 5 x 5 - y direction
    getDerivKernels(sobelX, sobelY, 0, 1, 5, false, CV_32F);
    cout << "sobel5y = " << endl << " " << sobelX*sobelY.t() << endl << endl;

    // 7 x 7 - x direction
    getDerivKernels(sobelX, sobelY, 1, 0, 7, false, CV_32F);
    cout << "sobel7x = " << endl << " " << sobelX*sobelY.t() << endl << endl;

    // 7 x 7 - y direction
    getDerivKernels(sobelX, sobelY, 0, 1, 7, false, CV_32F);
    cout << "sobel7y = " << endl << " " << sobelX*sobelY.t() << endl << endl;

    return 0;
}

      

Note that kernels x

and y

are both columns, so you need to transpose the vector y

so that it becomes a row vector to calculate the outer product.

+10


source


You can also take a look at my output for Sobel kernels of arbitrary sizes and angles here fooobar.com/questions/186381 / ...



0


source







All Articles