本文主要对opencv的Sobel导数、Scharr滤波器、Laplacian算子、Canny边缘检测的函数进行简单的说明。
1、Sobel导数
索贝尔算子(Sobel operator)是图像处理中的算子之一,主要用作边缘检测。在技术上,它是一离散性差分算子,用来运算图像亮度函数的梯度之近似值。在图像的任何一点使用此算子,将会产生对应的梯度矢量或是其法矢量。Sobel导数结合了高斯平滑和微分求导。
假设被作用图像为 :
在两个方向求导:
水平变化: 将 与一个奇数大小的内核 进行卷积。比如,当内核大小为3时, 的计算结果为:
垂直变化: 将:math:I 与一个奇数大小的内核 进行卷积。比如,当内核大小为3时, 的计算结果为:
在图像的每一点,结合以上两个结果求出近似 梯度:
有时也用下面更简单公式代替:
Calculates the first, second, third, or mixed image derivatives using an extended Sobel operator.
Parameters: |
|
---|
In all cases except one, the separable kernel is used to calculate the derivative. When , the or kernel is used (that is, no Gaussian smoothing is done). ksize = 1 can only be used for the first or the second x- or y- derivatives.
#include
#include
using namespace cv;
int main(void)
{
Mat src = imread("2.jpg", 0);
if (!src.data) {
return -1;
}
namedWindow("Sobel", CV_WINDOW_AUTOSIZE);
imshow("yuan", src);
Mat grayx, grayy;
Mat absgrayx, absgrayy;
Mat dst;
Sobel(src, grayx, -1, 1, 0); //有的参数如果使用默认值,则可以不用写出。
convertScaleAbs(grayx, absgrayx);
Sobel(src, grayy, -1, 0, 1);
convertScaleAbs(grayy, absgrayy);
addWeighted(absgrayx, 1, absgrayy, 1, 0, dst);
imshow("Sobel", dst);
waitKey(0);
return 0;
}
图一:ksize =3时。
图二:ksize = 5时。
注:Sobel导数有一个非常好的性质,即可以定义任意大小的核,并且这些核可以用快速且迭代方式构造,大核对导数有更好的逼近,因为小核对噪声更敏感。
为了更好的理解以上内容,我们必须认识到一点,即Sobel导数并不是真正的导数,因为Sobel算子定义于一个离散的空间之上。Sobel算子真正表示的是多项式拟合,也就是说,x方向上的二阶导数并不是真正的二阶导数。他是对抛物线函数的局部拟合。
2、Scharr滤波器
当内核大小为 时, 以上Sobel内核可能产生比较明显的误差(毕竟,Sobel算子只是求取了导数的近似值)。 为解决这一问题,OpenCV提供了 Scharr 函数,但该函数仅作用于大小为3的内核。该函数的运算与Sobel函数一样快,但结果却更加精确,其内核为:
Calculates the first x- or y- image derivative using Scharr operator.
Parameters: |
|
---|
The function computes the first x- or y- spatial image derivative using the Scharr operator. The call
is equivalent to
#include
#include
using namespace cv;
int main(void)
{
Mat src = imread("2.jpg", 0);
if (!src.data) {
return -1;
}
namedWindow("Sobel", CV_WINDOW_AUTOSIZE);
imshow("yuan", src);
Mat grayx, grayy;
Mat absgrayx, absgrayy;
Mat dst;
Scharr(src, grayx, -1, 1, 0);
//Sobel(src, grayx, -1, 1, 0, 3);
convertScaleAbs(grayx, absgrayx);
Scharr(src, grayy, -1, 0, 1);
//Sobel(src, grayy, -1, 0, 1, 3);
convertScaleAbs(grayy, absgrayy);
addWeighted(absgrayx, 1, absgrayy, 1, 0, dst);
imshow("Sobel", dst);
waitKey(0);
return 0;
}
图三:Scharr滤波器。
注:对于小核,Sobel算子的计数精度比较低。
对于3*3,Scharr滤波器同Sobel滤波器一样快,但精度更高。