目录

 一 边缘检测算子

1 Roberts算子

2 Sobel算子

3 Prewitt算子

二 实践

(1)代码

(2)结果图

        边缘检测是计算机视觉中的基本问题,边缘检测的难点就在于如何又快又准确地提取图像的边缘信息。

       边缘检测的基本方法有很多,基于一阶导数的边缘检测算子包括Roberts边缘检测算子、Sobel边缘检测算子、Prewitt边缘检测算子、Krisch边缘检测算子和罗盘边缘检测算子;而基于二阶导数的边缘检测算子有Marr-Hildreth、拉普拉斯(Laplacian)边缘检测算子、Canny边缘检测算子。拉普拉斯边缘检测算子对噪声较敏感。

 一 边缘检测算子

1 Roberts算子

        在数字图像处理中,Roberts边缘检测算子是最早的边缘检测算子之一。Roberts算子是一种利用局部差分算子寻找边缘的算子。Roberts算子边缘定位相对准确。在实际的应用中,Roberts边缘检测算子可用如下公式所示。

        Roberts边缘算子是一个2x2的模板,采用的是对角方向相邻的两个像素之差。用差分代替一阶偏导,算子表示如下公式所示。 

        在实际的应用中,图像中的每个像素点都用上述算子对应的两个 2X2 模板进行卷积运算,两个模板如下图所示。

2 Sobel算子

        Sobel边缘提取算法提供的边缘方向信息较准确,对噪声有一定的平滑效果,并且提取算法在空间上的实现较为容易。但是,Sobel算子提取的边缘定位的精度较低,同时会有伪边缘存在。Sobel边缘算子所采用的算法是先进行加权平均,然后进行微分运算。可以用差分代替一阶偏导,算子的计算方法公式如下。

        Sobel算子垂直方向模板可以检测出图像中的水平方向的边缘,Sobel水平模板则可以检测垂直方向的边缘。在实际的应用中,图像中的每一个像素点都用这两个卷积核分别进行卷积运算,取两个卷积的最大值作为该点的边缘输出值,运算结果是一幅边缘幅度图像。Sobel算子垂直方向和水平方向的模板如下图所示。

 3 Prewitt算子

        Prewitt边缘检测算子就是一种利用局部差分平均方法寻找边缘的算子。用差分代替一阶偏导可得算子如以下公式所示。

         与Sobel算子的方法一样,图像中的每一个像素点都用这两个卷积核分别进行卷积运算,取这两个卷积的最大值作为该点的边缘输出值,运算结果是一幅边缘幅度的图像。为了在检测边缘的同时能减少噪声所带来的影响,算子从加大边缘检测算子的角度出发,由2×2扩大到3×3来计算差分算子,Prewitt边缘检测算子的两个卷积模板如下图所示。

二 实践

(1)代码

import cv2

import matplotlib.pyplot as plt

import numpy as np

def dealImg(img):

b, g, r = cv2.split(img)

img_rgb = cv2.merge([r, g, b])

return img_rgb

def dealImageResult(img_path):

img = cv2.imread(img_path)

# 灰度化处理图像

grayImage = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

# 高斯滤波

Gaussian = cv2.GaussianBlur(grayImage, (3, 3), 0, 0, cv2.BORDER_DEFAULT)

# 自适应阈值处理

Binary = cv2.adaptiveThreshold(Gaussian, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 7, -2)

# Sobel算子

x = cv2.Sobel(Gaussian, cv2.CV_16S, 1, 0, ksize=3) # 对x求一阶导,垂直检测

y = cv2.Sobel(Gaussian, cv2.CV_16S, 0, 1, ksize=3) # 对y求一阶导,水平检测

absX = cv2.convertScaleAbs(x)

absY = cv2.convertScaleAbs(y)

Sobel = cv2.addWeighted(absX, 0.5, absY, 0.5, 0)

#Roberts算子

kernelx = np.array([[-1, 0], [0, 1]], dtype=int)

kernely = np.array([[0, -1], [1, 0]], dtype=int)

x = cv2.filter2D(Gaussian, cv2.CV_16S, kernelx)

y = cv2.filter2D(Gaussian, cv2.CV_16S, kernely)

absX = cv2.convertScaleAbs(x)

absY = cv2.convertScaleAbs(y)

Roberts = cv2.addWeighted(absX, 0.5, absY, 0.5, 0)

#Prewitt算子

kernelx = np.array([[1, 1, 1], [0, 0, 0], [-1, -1, -1]], dtype=int)

kernely = np.array([[-1, 0, 1], [-1, 0, 1], [-1, 0, 1]], dtype=int)

x = cv2.filter2D(Gaussian, cv2.CV_16S, kernelx)

y = cv2.filter2D(Gaussian, cv2.CV_16S, kernely)

absX = cv2.convertScaleAbs(x)

absY = cv2.convertScaleAbs(y)

Prewitt = cv2.addWeighted(absX, 0.5, absY, 0.5, 0)

# canny算子

cannyedges = cv2.Canny(Gaussian, 50, 150, apertureSize=3)

# Laplacian算子

Laplacian_tmp = cv2.Laplacian(Gaussian, cv2.CV_16S, ksize=3)

Laplacian = cv2.convertScaleAbs(Laplacian_tmp)

fig = plt.figure(figsize=(9, 9))

titles = ["img", "grayImage", "Gaussian", "Binary", "Sobel", "Roberts", "Prewitt", "Canny", "Laplacian"]

img = dealImg(img)

images = [img, grayImage, Gaussian, Binary, Sobel, Roberts, Prewitt, cannyedges, Laplacian]

for i in range(9):

plt.subplot(3, 3, i + 1), plt.imshow(images[i], 'gray')

plt.title(titles[i])

plt.xticks([]), plt.yticks([])

plt.show()

fig.savefig('test_results.jpg', bbox_inches='tight')

if __name__ == '__main__':

dealImageResult("2.jpg")

pass

(2)结果图

前文回顾

 目录:

1  数字图像处理(入门篇)一 图像的数字化与表示

2 数字图像处理(入门篇)二 颜色空间

3 数字图像处理(入门篇)三 灰度化

4 数字图像处理(入门篇)四 像素关系

5 数字图像处理(入门篇)五 图像数据预处理之颜色空间转换

6 数字图像处理(入门篇)六 图像数据预处理之坐标变化

7 数字图像处理(入门篇)七 图像数据预处理之灰度变化

8 数字图像处理(入门篇)八 图像数据预处理之直方图

9 数字图像处理(入门篇)九 图像数据预处理之滤波

 

参考链接

评论可见,请评论后查看内容,谢谢!!!评论后请刷新页面。