opencv的Sobel导数、Scharr滤波器、Laplacian算子、Canny边缘检测

本文主要对opencv的Sobel导数、Scharr滤波器、Laplacian算子、Canny边缘检测的函数进行简单的说明。


1、Sobel导数

      索贝尔算子(Sobel operator)是图像处理中的算子之一,主要用作边缘检测。在技术上,它是一离散性差分算子,用来运算图像亮度函数的梯度之近似值。在图像的任何一点使用此算子,将会产生对应的梯度矢量或是其法矢量。Sobel导数结合了高斯平滑和微分求导。

假设被作用图像为 I:

  1. 在两个方向求导:

    1. 水平变化: 将 I 与一个奇数大小的内核 G_{x} 进行卷积。比如,当内核大小为3时, G_{x} 的计算结果为:

      G_{x} = \begin{bmatrix}-1 & 0 & +1  \\-2 & 0 & +2  \\-1 & 0 & +1\end{bmatrix} * I

    2. 垂直变化: 将:math:I 与一个奇数大小的内核 G_{y} 进行卷积。比如,当内核大小为3时, G_{y} 的计算结果为:G_{y} = \begin{bmatrix}-1 & -2 & -1  \\0 & 0 & 0  \\+1 & +2 & +1\end{bmatrix} * I

  2. 在图像的每一点,结合以上两个结果求出近似 梯度:

    G = \sqrt{ G_{x}^{2} + G_{y}^{2} }

    有时也用下面更简单公式代替:

    G = |G_{x}| + |G_{y}|

Sobel

Calculates the first, second, third, or mixed image derivatives using an extended Sobel operator.

C++:  void  Sobel (InputArray  src, OutputArray  dst, int  ddepth, int  dx, int  dy, int  ksize=3, double  scale=1, double  delta=0, int  borderType=BORDER_DEFAULT  )
Parameters:
  • src – input image.
  • dst – output image of the same size and the same number of channels as src .
  • ddepth –
    output image depth; the following combinations of src.depth() and ddepth are supported:
    • src.depth() = CV_8Uddepth = -1/CV_16S/CV_32F/CV_64F
    • src.depth() = CV_16U/CV_16Sddepth = -1/CV_32F/CV_64F
    • src.depth() = CV_32Fddepth = -1/CV_32F/CV_64F
    • src.depth() = CV_64Fddepth = -1/CV_64F

    when ddepth=-1, the destination image will have the same depth as the source; in the case of 8-bit input images it will result in truncated derivatives.

  • xorder – order of the derivative x.
  • yorder – order of the derivative y.
  • ksize – size of the extended Sobel kernel; it must be 1, 3, 5, or 7.
  • scale – optional scale factor for the computed derivative values; by default, no scaling is applied (seegetDerivKernels() for details).
  • double类型的scale,计算导数值时可选的缩放因子,默认值是1,表示默认情况下是没有应用缩放的。我们可以在文档中查阅getDerivKernels的相关介绍,来得到这个参数的更多信息。
  • delta – optional delta value that is added to the results prior to storing them in dst.
  • borderType – pixel extrapolation method (see borderInterpolate for details).

In all cases except one, the \texttt{ksize} \times\texttt{ksize} separable kernel is used to calculate the derivative. When \texttt{ksize = 1} , the 3 \times 1 or 1 \times 3 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滤波器

当内核大小为 3 时, 以上Sobel内核可能产生比较明显的误差(毕竟,Sobel算子只是求取了导数的近似值)。 为解决这一问题,OpenCV提供了 Scharr 函数,但该函数仅作用于大小为3的内核。该函数的运算与Sobel函数一样快,但结果却更加精确,其内核为:

G_{x} = \begin{bmatrix}-3 & 0 & +3  \\-10 & 0 & +10  \\-3 & 0 & +3\end{bmatrix}G_{y} = \begin{bmatrix}-3 & -10 & -3  \\0 & 0 & 0  \\+3 & +10 & +3\end{bmatrix}

Scharr

Calculates the first x- or y- image derivative using Scharr operator.

C++: void Scharr(InputArray src, OutputArray dst, int ddepth, int dx, int dy, double scale=1, double delta=0, intborderType=BORDER_DEFAULT )
Python: cv2.Scharr(src, ddepth, dx, dy[, dst[, scale[, delta[, borderType]]]]) → dst
Parameters:
  • src – input image.
  • dst – output image of the same size and the same number of channels as src.
  • ddepth – output image depth (see Sobel() for the list of supported combination of src.depth() andddepth).
  • dx – order of the derivative x.
  • dy – order of the derivative y.
  • scale – optional scale factor for the computed derivative values; by default, no scaling is applied (seegetDerivKernels() for details).
  • delta – optional delta value that is added to the results prior to storing them in dst.
  • borderType – pixel extrapolation method (see borderInterpolate for details).

The function computes the first x- or y- spatial image derivative using the Scharr operator. The call

\texttt{Scharr(src, dst, ddepth, dx, dy, scale, delta, borderType)}

is equivalent to

\texttt{Sobel(src, dst, ddepth, dx, dy, CV\_SCHARR, scale, delta, borderType)} .


#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滤波器一样快,但精度更高。


你可能感兴趣的:(Opencv3.0学习)