Canny 边缘检测
Canny 边缘检测是一种被广泛应用的算法,效果较好
原理
详见 参考资料1
没搞懂,先记下来,空了研究吧
该方法使用了比高斯差分算法更复杂的技巧,如多向灰度梯度和滞后阈值化。
Canny边缘检测器算法基本步骤:
平滑图像:通过使用合适的模糊半径执行高斯模糊来减少图像内的噪声。
计算图像的梯度:这里计算图像的梯度,并将梯度分类为垂直、水平和斜对角。这一步的输出用于在下一步中计算真正的边缘。
非最大值抑制:利用上一步计算出来的梯度方向,检测某一像素在梯度的正方向和负方向上是否是局部最大值,如果是,则抑制该像素(像素不属于边缘)。这是一种边缘细化技术,用最急剧的变换选出边缘点。
用滞后阈值化选择边缘:最后一步,检查某一条边缘是否明显到足以作为最终输出,最后去除所有不明显的边缘。
opencv 用法
def Canny(image, threshold1, threshold2, edges=None, apertureSize=None, L2gradient=None)
- image 必须是单通道
- 其中较大的阈值threshold2用于检测图像中明显的边缘,但一般情况下检测的效果不会那么完美,边缘检测出来是断断续续的。所以这时候用较小的阈值threshold1将这些间断的边缘连接起来
- 可选参数中apertureSize就是Sobel算子的大小。
- L2gradient参数是一个布尔值,如果为真,则使用更精确的L2范数进行计算(即两个方向的倒数的平方和再开放),否则使用L1范数(直接将两个方向导数的绝对值相加)
返回一张二值图
示例
import cv2 import numpy as np img = cv2.imread('imgs/2.png', 0) # 转化为灰度图 blur = cv2.GaussianBlur(img, (3, 3), 0) # 用高斯滤波处理原图像降噪 canny = cv2.Canny(blur, 50, 150) # 50是最小阈值,150是最大阈值 # plot img_canny = np.hstack([img, canny]) cv2.namedWindow("canny", 0) # 可调大小 cv2.imshow('canny', img_canny) cv2.waitKey(0) cv2.destroyAllWindows()
效果图
soble 边缘检测
简单记下
opencv 用法
x = cv2.Sobel(img, cv2.CV_16S, 1, 0) y = cv2.Sobel(img, cv2.CV_16S, 0, 1) # cv2.convertScaleAbs(src[, dst[, alpha[, beta]]]) # 可选参数alpha是伸缩系数,beta是加到结果上的一个值,结果返回uint类型的图像 Scale_absX = cv2.convertScaleAbs(x) # convert 转换 scale 缩放 Scale_absY = cv2.convertScaleAbs(y) result = cv2.addWeighted(Scale_absX, 0.5, Scale_absY, 0.5, 0) # plot img_res = np.hstack([img, result]) cv2.namedWindow("result", 0) # 可调大小 cv2.imshow('result', img_res) cv2.waitKey(0) cv2.destroyAllWindows()
详见 《图像梯度》 章节
参考资料:
https://segmentfault.com/a/1190000015651403 opencv python Canny边缘检测
https://www.cnblogs.com/gezhuangzhuang/p/10711201.html 基本同上篇
https://www.jb51.net/article/203283.htm Python使用Opencv实现边缘检测以及轮廓检测的实现
https://zhuanlan.zhihu.com/p/38739563 边缘检测,框出物体的轮廓(使用opencv-python)
https://blog.csdn.net/qq_42333641/article/details/90201179 canny 和 soble边缘检测
https://www.cnblogs.com/silence-cho/p/13621975.html#top 更多边缘检测算法