⚠申明: 未经许可,禁止以任何形式转载,若要引用,请标注链接地址。 全文共计3077字,阅读大概需要3分钟
????更多学习内容, 欢迎????关注????【文末】我的个人微信公众号:不懂开发的程序猿
个人网站:/❗❗❗知识付费,????止白嫖,有需要请后台私信或【文末】个人微信公众号联系我
基于OpenCv的图像Canny边缘检测
- 基于OpenCv的图像Canny边缘检测
- 任务需求
- 任务目标
- 1、掌握使用Canny算子的步骤
- 2、掌握基于OpenCv进行Canny边缘检测
- 任务环境
- 1、jupyter开发环境
- 2、OpenCv
- 3、python3.6
- 任务实施过程
- 一、Canny边缘检测
- 1.导入所需要的工具包和图像
- 2.高斯滤波器平滑图像
- 边缘检测
- 算子与其他边缘检测算法对比
- 二、任务小结
- 说明
基于OpenCv的图像Canny边缘检测
任务需求
边缘检测是图像处理与识别中最基础、最重要的内容之一。一幅图像就是一个信息系统,其大量信息是由它的轮廓边缘提供的。对图像分析和理解的第一步常常是边缘检测。
例如,车牌照片预处理是汽车牌照识别系统中的一个重要的环节,预处理的好坏对车牌系统识别率影响很大,可以利用边缘检测对车牌定位得到车牌区域,获取轮廓,如下图。
任务目标
1、掌握使用Canny算子的步骤
2、掌握基于OpenCv进行Canny边缘检测
任务环境
1、jupyter开发环境
2、OpenCv
3、python3.6
任务实施过程
一、Canny边缘检测
Canny 边缘检测算法是一个多级边缘检测算法,也被很多人认为是边缘检测的最优算法。
Canny边缘检测步骤如下:
- 1.用高斯滤波器平滑图像:使用高斯滤波器消除图像中的噪声
- 2.用一阶偏导有限差分计算梯度幅值和方向:一般使用Sobel算子核在水平和垂直方向上对平滑的图像进行滤波
- 3.对梯度幅值进行非极大值抑制:对于梯度幅值图像,仅保留梯度方向的极大值点
在梯度方向的沿线上检测该点是否为局部极大值,得到的结果图像包含边缘的宽度为1个像素
- 4.用双阈值算法检测和连接边缘
梯度值>maxVal:则为边界(强边界)
minVal<梯度值<maxVal:如果连接有强边界则保留,否则舍弃
梯度值<minVal:不是边界
1.导入所需要的工具包和图像
import cv2 # 导入opencv
import matplotlib.pyplot as plt # 导入绘图模块
import numpy as np # 导入numpy库
from utils import im_show # 导入显示图像函数
# 绘制图像直接展示,不用调用()
%matplotlib inline
# 用来正常显示中文标签
plt.rc('font',family="SimHei")
# 读取图像,0 按单通道的方式读入图像,即灰白图像
img = cv2.imread(r'./experiment/data/',0)
# 设置画布大小
plt.figure(figsize=(6,6))
# 显示图像
im_show('原图像',img)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
2.高斯滤波器平滑图像
先对原始图像使用 3 ∗ 3 3*3 3∗3高斯卷积核和 5 ∗ 5 5*5 5∗5高斯卷积核对图像进行平滑处理
(img, ksize,sigmaX,sigmaY)
- img:原图像
- ksize:表示进行高斯滤波的卷积核大小
- sigmaX:X 方向的高斯核标准差
- sigmaY:Y 方向的高斯核标准差,如果仅指定了sigmaX,则sigmaY与sigmaX相同。如果两者都为 0,则可以根据 ksize 来计算得到。
# 高斯滤波,使用不同尺寸的高斯卷积核对图像进行卷积平滑
blur3 = cv2.GaussianBlur(img, (3, 3), 0)
blur5 = cv2.GaussianBlur(img, (5, 5), 0)
plt.figure(figsize=(12,12))
# 显示图像进行高斯平滑后的结果
im_show('原图像高斯平滑后的图像',np.hstack((blur3,blur5)))
- 1
- 2
- 3
- 4
- 5
- 6
边缘检测
(image, threshold1, threshold2, apertureSize)
- image:原图像
- threshold1:阈值1(小)
- threshold2:阈值2(大)
- apertureSize:可选参数,Sobel算子的大小
# 使用Canny函数进行边缘检测
# 放入高斯平滑后的图像blur3和blur5
# 设置双阈值 最小阈值50 最大阈值150
canny1 = cv2.Canny(blur3, 50, 150)
canny2 = cv2.Canny(blur5, 50, 150)
# 设置双阈值 最小阈值50 最大阈值100
canny3 = cv2.Canny(blur3, 50, 100)
# 设置双阈值 最小阈值80 最大阈值100
canny4 = cv2.Canny(blur5, 80, 150)
# 创建一个列表l,放入四个Canny边缘结果
l = [canny1,canny2,canny3,canny4]
# 创建一个列表g,放入四个高斯平滑高斯核尺寸
g = ['3*3','5*5','3*3','5*5']
# 创建一个列表y,放入Canny函数中设置的大、小阈值
y = ['(50,150)','(50,150)','(50,100)','(80,150)']
plt.figure(figsize=(12,12))
# 使用for循环,绘制四个边缘结果的图像
for i in range(4):
plt.subplot(2,2,i+1)
im_show('1',l[i])
# 设置子图标题和字体大小
plt.title('高斯滤波尺寸为{}和双阈值为{}的边缘检测'.format(g[i],y[i]),fontsize=15)
# 调整子图距离
plt.tight_layout()
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
设置大小阈值分别为 T 1 T_1 T1, T 2 T_2 T2,对于同一个高斯核对图像进行高斯平滑后:
- 大于 T 2 T_2 T2的边缘是强边界, T 2 T_2 T2的值减小,高阈值宽松,得到的强边缘变多,总体边缘变多。
- 大于 T 1 T_1 T1小于 T 2 T_2 T2的边缘是弱边界,弱边界与强边界相连的部分是边缘, T 1 T_1 T1的值增大,低阈值得到的弱边界变少,弱边界与强边界相连的部分也随之变少,总体边缘变少。
- 一般推荐的高低阈值比值为 T 2 T_2 T2: T 1 T_1 T1 = 3:1/2:1
算子与其他边缘检测算法对比
对于使用高斯平滑(高斯核: 3 ∗ 3 3*3 3∗3)后的图像进行不同方法的边缘检测并查看其检测结果
# 1.图像梯度获取边缘
# 首先将图像二值化,使用阈值函数,设置阈值为60,像素值超过60则赋值为255
_,Thr_img = cv2.threshold(blur3,60,255,cv2.THRESH_BINARY)
# 设置5*5卷积核
kernel = np.ones((5,5),np.uint8)
# 放入二值化后的图像,cv2.MORPH_GRADIENT表示图像梯度计算:膨胀-腐蚀
gradient = cv2.morphologyEx(Thr_img, cv2.MORPH_GRADIENT, kernel)
# 2.高斯拉普拉斯(LoG)边缘检测:高斯模糊+Laplacian
# cv2.CV_64F输出图像深度(数据类型),允许结果是负值
# 需要用convertScaleAbs()函数将其转回原来的uint8形式
log = cv2.Laplacian(blur3,cv2.CV_64F,ksize=3)
log = cv2.convertScaleAbs(log)
# 算子边缘检测
# 参数1,0 为只在x方向求一阶导数
sobel_x = cv2.Sobel(blur3,cv2.CV_64F,1,0,ksize=3)
sobel_x = cv2.convertScaleAbs(sobel_x)
# 参数0,1 为只在y方向求一阶导数
sobel_y = cv2.Sobel(blur3,cv2.CV_64F,0,1,ksize=3)
sobel_y = cv2.convertScaleAbs(sobel_y)
# 将两个方向卷积得到的边缘进行图像融合
sobelxy = cv2.addWeighted(sobel_x,0.5,sobel_y,0.5,0)
# 创建一个列表,放入四个得到的边缘结果
edge_list = [canny3,gradient,log,sobelxy]
# 创建一个列表,放入4个算子名
label = ['Canny','Gradient','LoG','Sobel']
plt.figure(figsize=(12,12))
# 使用for循环,绘制4个边缘的结果
for i in range(4):
plt.subplot(2,2,i+1)
im_show('1',edge_list[i])
# 设置子图标题,设置标题字体大小
plt.title('{}算子边缘检测结果'.format(label[i]),fontsize = 15)
# 调整子图之间的距离
plt.tight_layout()
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
二、任务小结
本次实验主要完成基于Canny算子对图像边缘的检测。可以看到相对于形态学梯度计算、LoG算子、Sobel算子得到的图像边缘,Canny算子是一个具有滤波、最强和检测的多阶段的优化算子,有高定位精度、低误判率、抑制虚假边缘的特点,适用于高噪声图像。
通过本次实验需要掌握以下内容:
- 1.掌握Canny算子进行边缘检测的步骤
- 2.掌握不同的Canny算子阈值对图像边缘的检测结果的影响
–end–
说明
本实验(项目)/论文若有需要,请后台私信或【文末】个人微信公众号联系我