youcans 的 OpenCV 例程200篇150. 边缘检测梯度算子

Posted 小白YouCans

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了youcans 的 OpenCV 例程200篇150. 边缘检测梯度算子相关的知识,希望对你有一定的参考价值。

欢迎关注 『youcans 的 OpenCV 例程 200 篇』 系列,持续更新中
欢迎关注 『youcans 的 OpenCV学习课』 系列,持续更新中


【youcans 的 OpenCV 例程200篇】150. 边缘检测梯度算子


2. 点、线和边缘检测

本节基于图像灰度的不连续性,讨论根据灰度的突变检测边界,以此为基础进行图像分割。

  • 边缘像素是图像中灰度突变的像素,而边缘是相连边缘像素的集合。
  • 线是一条细边缘线段,其两侧的背景灰度与线段的像素灰度存在显著差异。
  • 孤立的点是一个被背景像素围绕的前景像素,或一个被前景像素围绕的背景像素。

导数可以用来检测灰度的局部突变:

  • 一阶导数通常产生粗边缘;
  • 二阶导数对精细细节(如细线、孤立点和噪声)的响应更强;
  • 二阶导数在灰度斜坡和台阶过渡处会产生双边缘响应,即二阶导数在进入和离开边缘时的符号相反;
  • 二阶导数的符号可用于确定边缘的过渡是从亮到暗还是从暗到亮。

计算图像中每个像素位置的一阶导数和二阶导数的方法是空间卷积。对一个 3*3 模板,计算模板区域内灰度值与模板系数的卷积。


2.4 边缘检测的常用梯度算子

边缘检测的基本方法通常是基于一阶导数和二阶导数的,因此需要进行图像的梯度计算。图像的梯度可以用一阶导数和二阶偏导数来求解。

以矩阵形式表达的数字图像 f,任意位置 (x,y) 的梯度 ∇ f \\nabla f f 定义为向量:
∇ f = g r a d ( f ) = [ g x g y ] = [ ∂ f / ∂ x ∂ f / ∂ x ] \\nabla f = grad(f) =\\beginbmatrix g_x \\\\ g_y \\endbmatrix =\\beginbmatrix \\partial f /\\partial x \\\\ \\partial f /\\partial x \\endbmatrix f=grad(f)=[gxgy]=[f/xf/x]
梯度算子的前向差分公式为:
g x ( x , y ) = ∂ f ( x , y ) ∂ x = f ( x + 1 , y ) − f ( x , y ) g y ( x , y ) = ∂ f ( x , y ) ∂ y = f ( x , y + 1 ) − f ( x , y ) g_x(x,y) = \\dfrac\\partial f(x,y)\\partial x = f(x+1,y) - f(x,y) \\\\ g_y(x,y) = \\dfrac\\partial f(x,y)\\partial y = f(x,y+1) - f(x,y) \\\\ gx(x,y)=xf(x,y)=f(x+1,y)f(x,y)gy(x,y)=yf(x,y)=f(x,y+1)f(x,y)
梯度向量的幅度 M 和角度 α \\alpha α 为:
M ( x , y ) = ∣ ∣ ∇ f ∣ ∣ = g x 2 + g y 2 α ( x , y ) = a r c t a n [ g y / g x ] M(x,y) = ||\\nabla f|| = \\sqrt g_x^2 + g_y^2 \\\\ \\alpha (x,y) = arctan[g_y / g_x] M(x,y)=f=gx2+gy2 α(x,y)=arctan[gy/gx]
在实际编程中,为了减少计算量,常用绝对值来近似梯度幅度:
M ( x , y ) ≈ ∣ g x ∣ + ∣ g y ∣ M(x,y) \\approx |g_x| + |g_y| M(x,y)gx+gy
根据梯度算子的定义和基本公式,可以发展多种不同的计算算法,称为梯度算子。对于图像的梯度计算,通常采用模板(卷积核)对原图像进行卷积运算来实现。

Robert 梯度算子:
简单的交叉差分算法,利用局部差分算子寻找边缘,采用对角线相邻两像素差作为梯度值检测边缘。形式简单,计算速度快,但对噪声敏感,无法抑制噪声。

Prewitt 算子:
利用两个方向模板与图像进行邻域卷积,一个方向模板检测水平边缘,另一个检测垂直边缘。能够抑制噪声,但对边缘的定位较 Roberts 算子差。

Sobel 算子:
是高斯平滑和微分求导的联合运算,抗噪声能力强。考虑了距离对权值的影响,距离越远的像素的影响越小。可以通过快速卷积实现,简单有效,应用广泛。

Isotropic Sobel 算子:
权值反比于中心距,具有各向同性,沿不同方向检测边缘时梯度幅度一致。

Scharr 算子:
是 Sobel 算子在 ksize=3 时的优化,在平滑部分中心元素占的权重更大,相当于使用更瘦高的平滑模板。与 Sobel 的速度相同,精度更高。

Lapacian 算子:
二阶微分算子,具有各向同向性,与坐标轴无关(无法检测方向)。对噪声非常敏感,可以先进行阈值处理或平滑处理。

这些基本的一阶、二阶微分算子如 Robert、Sobel、Prewitt、Laplacian 等,本质上都可以用于检测边缘,也被称为边缘检测算子。进一步地,考虑边缘和噪声的性质,可以改进边缘检测算子,如 Marr-Hildreth 算子、Canny 算子。


例程 11.4:边缘检测梯度算子

    # 11.4 边缘检测的梯度算子 (Roberts 算子, Prewitt 算子, Sobel 算子, Laplacian 算子)
    img = cv2.imread("../images/Fig1016a.tif", flags=0)  # 读取为灰度图像

    # 自定义卷积核
    # Roberts 边缘算子
    kernel_Roberts_x = np.array([[1, 0], [0, -1]])
    kernel_Roberts_y = np.array([[0, -1], [1, 0]])
    # Prewitt 边缘算子
    kernel_Prewitt_x = np.array([[-1, 0, 1], [-1, 0, 1], [-1, 0, 1]])
    kernel_Prewitt_y = np.array([[1, 1, 1], [0, 0, 0], [-1, -1, -1]])
    # Sobel 边缘算子
    kernel_Sobel_x = np.array([[-1, 0, 1], [-2, 0, 2], [-1, 0, 1]])
    kernel_Sobel_y = np.array([[1, 2, 1], [0, 0, 0], [-1, -2, -1]])
    # Laplacian 边缘算子
    kernel_Laplacian_K1 = np.array([[0, 1, 0], [1, -4, 1], [0, 1, 0]])
    kernel_Laplacian_K2 = np.array([[1, 1, 1], [1, -8, 1], [1, 1, 1]])

    # 卷积运算
    imgBlur = cv2.blur(img, (3,3))  # Blur 平滑后再做 Laplacian 变换
    imgLaplacian_K1 = cv2.filter2D(imgBlur, -1, kernel_Laplacian_K1)
    imgLaplacian_K2 = cv2.filter2D(imgBlur, -1, kernel_Laplacian_K2)
    imgRoberts_x = cv2.filter2D(img, -1, kernel_Roberts_x)
    imgRoberts_y = cv2.filter2D(img, -1, kernel_Roberts_y)
    imgRoberts = np.uint8(cv2.normalize(abs(imgRoberts_x) + abs(imgRoberts_y), None, 0, 255, cv2.NORM_MINMAX))
    imgPrewitt_x = cv2.filter2D(img, -1, kernel_Prewitt_x)
    imgPrewitt_y = cv2.filter2D(img, -1, kernel_Prewitt_y)
    imgPrewitt = np.uint8(cv2.normalize(abs(imgPrewitt_x) + abs(imgPrewitt_y), None, 0, 255, cv2.NORM_MINMAX))
    imgSobel_x = cv2.filter2D(img, -1, kernel_Sobel_x)
    imgSobel_y = cv2.filter2D(img, -1, kernel_Sobel_y)
    imgSobel = np.uint8(cv2.normalize(abs(imgSobel_x) + abs(imgSobel_y), None, 0, 255, cv2.NORM_MINMAX))

    plt.figure(figsize=(12, 8))
    plt.subplot(341), plt.title('Origin'), plt.imshow(img, cmap='gray'), plt.axis('off')
    plt.subplot(345), plt.title('Laplacian_K1'), plt.imshow(imgLaplacian_K1, cmap='gray'), plt.axis('off')
    plt.subplot(349), plt.title('Laplacian_K2'), plt.imshow(imgLaplacian_K2, cmap='gray'), plt.axis('off')
    plt.subplot(342), plt.title('Roberts'), plt.imshow(imgRoberts, cmap='gray'), plt.axis('off')
    plt.subplot(346), plt.title('Roberts_X'), plt.imshow(imgRoberts_x, cmap='gray'), plt.axis('off')
    plt.subplot(3,4,10), plt.title('Roberts_Y'), plt.imshow(imgRoberts_y, cmap='gray'), plt.axis('off')
    plt.subplot(343), plt.title('Prewitt'), plt.imshow(imgPrewitt, cmap='gray'), plt.axis('off')
    plt.subplot(347), plt.title('Prewitt_X'), plt.imshow(imgPrewitt_x, cmap='gray'), plt.axis('off')
    plt.subplot(3,4,11), plt.title('Prewitt_Y'), plt.imshow(imgPrewitt_y, cmap='gray'), plt.axis('off')
    plt.subplot(344), plt.title('Sobel'), plt.imshow(imgSobel, cmap='gray'), plt.axis('off')
    plt.subplot(348), plt.title('Sobel_X'), plt.imshow(imgSobel_x, cmap='gray'), plt.axis('off')
    plt.subplot(3,4,12), plt.title('Sobel_Y'), plt.imshow(imgSobel_y, cmap='gray'), plt.axis('off')
    plt.tight_layout()
    plt.show()


(本节完)


版权声明:

youcans@xupt 原创作品,转载必须标注原文链接:(https://blog.csdn.net/youcans/article/details/124073181)

Copyright 2022 youcans, XUPT
Crated:2022-4-10


欢迎关注 『youcans 的 OpenCV 例程 200 篇』 系列,持续更新中
欢迎关注 『youcans 的 OpenCV学习课』 系列,持续更新中

【youcans 的 OpenCV 例程200篇】01. 图像的读取(cv2.imread)
【youcans 的 OpenCV 例程200篇】02. 图像的保存(cv2.imwrite)
【youcans 的 OpenCV 例程200篇】03. 图像的显示(cv2.imshow)
【youcans 的 OpenCV 例程200篇】04. 用 matplotlib 显示图像(plt.imshow)
【youcans 的 OpenCV 例程200篇】05. 图像的属性(np.shape)
【youcans 的 OpenCV 例程200篇】06. 像素的编辑(img.itemset)
【youcans 的 OpenCV 例程200篇】07. 图像的创建(np.zeros)
【youcans 的 OpenCV 例程200篇】08. 图像的复制(np.copy)
【youcans 的 OpenCV 例程200篇】09. 图像的裁剪(cv2.selectROI)
【youcans 的 OpenCV 例程200篇】10. 图像的拼接(np.hstack)
【youcans 的 OpenCV 例程200篇】11. 图像通道的拆分(cv2.split)
【youcans 的 OpenCV 例程200篇】12. 图像通道的合并(cv2.merge&

以上是关于youcans 的 OpenCV 例程200篇150. 边缘检测梯度算子的主要内容,如果未能解决你的问题,请参考以下文章

youcans 的 OpenCV 例程200篇182.基于形态学梯度的分水岭算法

youcans 的 OpenCV 例程200篇结束语

youcans的OpenCV例程200篇总目录

youcans 的 OpenCV 例程200篇179.图像分割之 GrabCut 图割法(掩模图像)

youcans 的 OpenCV 例程200篇201. 图像的颜色空间转换

OpenCV 例程200篇 目录-202205更新