Canny边缘检测:
1)应用非极大值(Non-Maximum Suppression)抑制,以消除边缘检测带来的杂散响应。 2)应用双阈值(Double-Threshold)检测来确定真实的和潜在的边缘。 3)通过抑制孤立的弱边缘最终完成边缘检测。
1、非极大值抑制
? ? ? ? ? ?
? ? ? ?线性插值法:设g1的梯度幅值M(g1),g2的梯度幅值M(g2),则dtmp1可以很得到:M(dtmp1)=w*M(g2)+(1-w)*M(g1) 其中w=distance(dtmp1,g2)/distance(g1,g2),? distance(g1,g2)表示两点之间的距离。
? ? ? ?为了简化计算,由于一个像素周围有八个像素,把一个像素的梯度方向离散为八个方向,这样就只需计算前后即可,不用插值了。
?
2、双阈值检测
1)梯度值>maxVal:则处理为边界
如图水平直线maxVal即为该检测要求的上边界,超过maxVal的像素点(如图A点)则处理为边界
2)minVal<梯度值<maxVal:连有边界则保留,否则舍弃
如图在水平直线maxVal和水平直线minVal之间的像素点(如图B,C点),当像素点所在线性曲线连有边界(即C点)时,则保留该像素点;当像素点所在线性曲线没有连有边界(即B点)时,则舍弃该像素点
3)梯度值<minVal:则舍弃
如图水平直线minVal即为该检测要求的下边界,低于minVal的像素点(如图D点)则舍弃该像素点
根据上述描写保留像素点的检测方法,当maxVal越小、minVal越大(始终遵守maxVal>minVal)时,所保留的像素点数量越少,检测描绘的图像更加简洁但同时缺少细节;当maxVal越大、minVal越小时,所保留的像素点数量变多,检测描绘的图像增加更多细节但同时会因为像素点的增多导致图像的混乱模糊。下面来看一个实例:
import cv2
import matplotlib.pyplot as plt
import numpy as np
%matplotlib inline
#创建显示图像的函数cv_show(name,img)来展示检测后的图像
def cv_show(name,img):
cv2.imshow(name,img)
cv2.waitKey(0)
cv2.destroyAllWindows()
#读取电脑中的图像,并转换为灰白图片
img=cv2.imread("D:\\tu\lena.jpg",cv2.IMREAD_GRAYSCALE)
#设定两个检测标准,其中v1检测像素点较多,v2检测像素点较少
v1=cv2.Canny(img,140,210)
v2=cv2.Canny(img,50,100)
#将检测后的图像显示
res=np.hstack((v1,v2))
cv_show("res",res)
?
?
|