对于大于 3 x 3 的尺寸,OpenCV 的 Sobel 滤波器的内核系数是多少?

Posted

技术标签:

【中文标题】对于大于 3 x 3 的尺寸,OpenCV 的 Sobel 滤波器的内核系数是多少?【英文标题】:What are the kernel coefficients for OpenCV's Sobel filter for sizes larger than 3 x 3? 【发布时间】:2015-10-22 02:47:23 【问题描述】:

我正在使用大小为 5x5 和 7x7 的 OpenCV 的 Sobel 滤波器来计算图像导数。

有人可以告诉我 OpenCV 中尺寸为 5x5 和 7x7 的 Sobel 滤波器的内核值吗?在进行 Google 搜索时,它向我展示了许多不同的内核。

以下是 5 x 5 的一些示例:

1。可分离的

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 。不可分离的

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。奇怪的不可分离

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

【问题讨论】:

看看:***.com/questions/9567882/… 【参考方案1】:

如果您真的想看看 OpenCV 使用什么,可以使用getDerivKernels 来确定 Sobel 滤波器的内核系数。你需要做的是指定你想要的方向和你想要的蒙版的大小。因此,每个内核大小有两个方向,因此我们需要调用四次。

但是,返回的是水平的x 和垂直的y,代表 Sobel 滤波器的 1D 内核,您可以使用它们通过 sepFilter2D 执行可分离的 2D 滤波。如果您真的想查看内核本身,您只需在xy 内核之间使用outer product,这些内核是从getDerivKernels 返回的。

下面是使用 Python 的 OpenCV 界面快速显示 5 x 5 xy 和 7 x 7 xy 内核:

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 中有一个标志,可让您标准化掩码。

还要注意,给定尺寸的一个掩码是另一个掩码的转置,如果您想检测特定方向的边缘,这很有意义。


为了完整起见,这里是上述 Python 代码的 C++ 版本。要编译代码,请将其放入文件中...调用它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;

请注意,xy 内核都是列向量,因此您需要转置 y 向量,使其成为计算外积的行向量。

【讨论】:

对于 x 导数,np.outer(sobel5x[0], sobel5x[1]) 不应该是 np.outer(sobel5x[1], sobel5x[0]) 吗? (虽然它们只是相互转置)【参考方案2】:

您可能还想在这里查看我对任意大小和角度的 Sobel 内核的推导https://***.com/a/41065243/2424669

【讨论】:

以上是关于对于大于 3 x 3 的尺寸,OpenCV 的 Sobel 滤波器的内核系数是多少?的主要内容,如果未能解决你的问题,请参考以下文章

在 OpenCV 中训练级联分类器的负样本图像尺寸?

opencv矩阵运算

C++ & OpenCV 断言失败

Windows 下 Python 3.x 的 OpenCV [重复]

8)对于带有 : 的语句

python3.x :安装opencv