【1】引言
前序学习进程中,在对图像进行边缘识别的基础上,先后进行了边缘轮廓绘制,矩形标注、圆形标注和凸包标注。相关文章包括且不限于:
python学opencv|读取图像(六十四)使用cv2.findContours()函数+cv2.drawContours()函数实现图像轮廓识别和标注-CSDN博客
python学opencv|读取图像(六十五)使用cv2.boundingRect()函数实现图像轮廓矩形标注-CSDN博客
python学opencv|读取图像(六十六)使用cv2.minEnclosingCircle函数实现图像轮廓圆形标注-CSDN博客
实际上,除了按照边缘轮廓来绘制线条进行标注外,其他的三种标注方式都不够精确,而且对图像的构成要求很高。但按照边缘轮廓来绘制线条进行标注,需要调用两个函数,先识别边缘,再绘制线条,实际上的描边效果会有一些线条的堆砌,整体效果依然不够精准和高效。
为此,如果有一种直接进行边缘检测然后标注的方法,将会使得图像识别的效果大大增强。这就是本次课程学习的目标:使用cv2.Canny()函数实现图像边缘检测。
【2】官网教程
点击下述链接,直达cv2.Canny()函数的官网教程:
OpenCV: Feature Detection
官网页面对 cv2.Canny()函数的说明为:
图1 官网页面对 cv2.Canny()函数的说明
相应的,官网页面对 cv2.Canny()函数的参数说明为:
cv.Canny(
image #输入图像
threshold1 #第一个阈值
threshold2 #第二个阈值
edges #输出图像
apertureSize #sober operator的尺寸,可选参数,暂无需关注
L2gradient )
关于 apertureSize 对应的sober operator的尺寸,可以通过下述链接了解:
OpenCV: Sobel Derivatives
【3】代码测试
首先引入必要模块,进行图像读取:
import cv2 as cv # 引入CV模块
import numpy as np #引入numpy模块# 读取图片
src = cv.imread('srcoo.png') #读取图像
然后进行图像边缘检测:
#边缘检测
r1=cv.Canny(src,10,50) #边缘检测
r2=cv.Canny(src,100,150) #边缘检测
r3=cv.Canny(src,255,500) #边缘检测
r4=cv.Canny(src,255,800) #边缘检测
上述不同的检测输出,是由于上下的阈值不同。
然后进行图像显示和保存:
#显示和保存图像
r5=np.hstack((r3,r4))
cv.imshow('r',src)
cv.imshow('r1',r1)
cv.imshow('r2',r2)
cv.imshow('r3',r3)
cv.imshow('r5',r5)cv.waitKey() # 图像不关闭
cv.destroyAllWindows() # 释放所有窗口
图像运行相关的图像有:
图2 初始图像
图3 阈值(10,50)对应检测效果Canny-r1.png
图4 阈值(100,150)对应检测效果Canny-r2.png
图5 阈值(255,500)对应检测效果Canny-r3.png
图5 阈值(255,500)和(255,800)对应检测效果Canny-r5.png
由图2到图5可见,随之阈值的增大,图像的细节越来越少;随之阈值差距的增大,图像的细节也越来越少。
此时的完整代码为:
import cv2 as cv # 引入CV模块
import numpy as np #引入numpy模块# 读取图片
src = cv.imread('srcoo.png') #读取图像#边缘检测
r1=cv.Canny(src,10,50) #边缘检测
r2=cv.Canny(src,100,150) #边缘检测
r3=cv.Canny(src,255,500) #边缘检测
r4=cv.Canny(src,255,800) #边缘检测
#b=cv.split(r2)
#g=cv.split(r4)
#print('r3.shape=',r3.shape)
#print('b=',b)
#print('g=',g)#显示和保存图像
r5=np.hstack((r3,r4))
cv.imshow('r',src)
cv.imshow('r1',r1)
cv.imwrite('Canny-r1.png', r1) #保存图像
cv.imshow('r2',r2)
cv.imwrite('Canny-r2.png', r2) #保存图像
cv.imshow('r3',r3)
cv.imwrite('Canny-r3.png', r3) #保存图像
cv.imshow('r5',r5)
cv.imwrite('Canny-r5.png', r5) #保存图像cv.waitKey() # 图像不关闭
cv.destroyAllWindows() # 释放所有窗口
【4】细节说明
如果仔细思考,会发现阈值可以使用超过255的数据。
这是因为cv2.Canny函数对应的算法中:阈值的低值是进行阈值转化的判断开关,而阈值的高值则直接影响了如何进行阈值转化。官网的说明页中,没有对阈值进行限制。
The smallest value between threshold1 and threshold2 is used for edge linking. The largest value is used to find initial segments of strong edges
【5】总结
掌握了python+opencv通过使用cv2.Canny()函数对图像进行边缘检测的技巧。