Я использую фильтр Собел OpenCV размером 5×5 и 7×7 для вычисления производной изображения.
Может кто-нибудь, пожалуйста, дайте мне знать значения ядра для фильтра Собеля размером 5×5 и 7×7 в OpenCV? При поиске в Google он показывает мне много разных ядер.
Вот несколько примеров для 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
Ты можешь использовать getDerivKernels
определить коэффициенты ядра для фильтра Собеля, если вы действительно хотите увидеть, что использует OpenCV. Что вам нужно сделать, это указать, какое направление вы хотите, и размер маски вы хотите. Таким образом, существует два направления на размер ядра, поэтому нам нужно вызвать это четыре раза.
Однако то, что возвращается, является горизонтальным, x
и вертикальный, y
, 1D-ядра, представляющие фильтр Собеля, который вы можете использовать для выполнения раздельной 2D-фильтрации через sepFilter2D
. Если вы действительно хотите увидеть сами ядра, вы просто берете внешний продукт между x
а также y
ядра, которые возвращаются из getDerivKernels
,
Вот что-то быстрое, используя интерфейс Python OpenCV, чтобы показать 5 х 5 x
, y
и 7 х 7 x
а также 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)
Обратите внимание, что ядра не нормализуются. Если вы хотите использовать их для фильтрации, вам, вероятно, следует нормализовать ядра. Там есть флаг getDerivKernels
это позволит вам нормализовать маску.
Также обратите внимание, что одна маска для данного размера является транспонированной для другой, что имеет смысл, если вы хотите обнаружить края для определенной ориентации.
Для полноты, вот версия C ++ вышеупомянутого кода Python. Чтобы скомпилировать код, поместите его в файл … назовите его test.cpp
затем сделайте это в терминале:
g++ -Wall -g -o test test.cpp `pkg-config --cflags --libs opencv`
После компиляции запустите программу, используя ./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;
}
Обратите внимание, что x
а также y
Ядра являются векторами столбцов, поэтому вам нужно транспонировать y
вектор, так что он становится вектором строки для вычисления внешнего произведения.
Вы также можете посмотреть мой вывод о ядрах Собеля произвольных размеров и углов здесь https://stackoverflow.com/a/41065243/2424669