I am using OpenCV's Sobel filter of size 5x5 and 7x7 to calculate the image derivative.
Could someone please let me know the kernel values for the Sobel filter of size 5x5 and 7x7 in OpenCV? When doing a Google search, it's showing me a lot of different kernels.
Here are some examples for 5 x 5:
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 1 0 -1 -2
4 10 0 -4 -10
7 17 0 -17 -7
4 10 0 -4 -10
2 1 0 -1 -2
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
You can use getDerivKernels
to determine the kernel coefficients for the Sobel filter if you really want to see what OpenCV uses. What you need to do is specify which direction you want and the size of the mask you want. As such, there are two directions per size of the kernel, so we need to call this four times.
However, what is returned are the horizontal, x
, and vertical, y
, 1D kernels that represent the Sobel filter which you can use to perform separable 2D filtering via sepFilter2D
. If you actually want to see the kernels themselves, you simply take the outer product between the x
and y
kernels that are returned from getDerivKernels
.
Here's something quick using Python's OpenCV interface to show the 5 x 5 x
, y
and 7 x 7 x
and y
kernels:
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)
Note that the kernels are not normalized. If you want to use these for filtering, you should probably normalize the kernels. There's a flag in getDerivKernels
that will allow you to normalize the mask.
Also notice that one mask for a given size is the transpose of the other, which makes sense if you want to detect edges for a particular orientation.
For completeness, here's the C++ version of the above Python code. To compile the code, place this into a file... call it test.cpp
, then do this in the 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 the x
and y
kernels are both column vectors, so you need transpose the y
vector so that it becomes a row vector to compute the outer product.
You might also want to take a look at my derivation for Sobel kernels of arbitrary sizes and angles here https://stackoverflow.com/a/41065243/2424669
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With