Canny 的目标是找到一个最优的边缘检测算法,最优边缘检测的含义是:
(1)最优检测:算法能够尽可能多地标识出图像中的实际边缘,漏检真实边缘的概率和误检非边缘的概率都尽可能小;
(2)最优定位准则:检测到的边缘点的位置距离实际边缘点的位置最近,或者是由于噪声影响引起检测出的边缘偏离物体的真实边缘的程度最小;
(3)检测点与边缘点一一对应:算子检测的边缘点与实际边缘点应该是一一对应
Canny边缘检测算法可以分为以下5个步骤:
应用高斯滤波来平滑图像,目的是去除噪声
找寻图像的强度梯度(intensity gradients)
应用非最大抑制(non-maximum suppression)技术来消除边误检(本来不是但检测出来是)
应用双阈值的方法来决定可能的(潜在的)边界
利用滞后技术来跟踪边界
python实现源码如下:
import cv2
def edge_demo(image):
blurred = cv2.GaussianBlur(image, (3, 3), 0)
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
xgrad = cv2.Sobel(gray, cv2.CV_16SC1, 1, 0)
ygrad = cv2.Sobel(gray, cv2.CV_16SC1, 1, 0)
# edge_output = cv2.Canny(xgrad, ygrad, 50, 150)
# cv2.imshow("Vannt_edge",edge_output)
edge_output = cv2.Canny(gray, 50, 150)
cv2.imshow("canny edge", edge_output)
dst = cv2.bitwise_and(image, image, mask=edge_output)
cv2.imshow("color edge", dst)
if __name__ == "__main__":
img = cv2.imread("image/img5.jpg")
cv2.namedWindow("input image", cv2.WINDOW_AUTOSIZE)
cv2.imshow("input image", img)
edge_demo(img)
cv2.waitKey(0)
cv2.destroyAllWindows()
直接调用Canny算法在单通道图像中查找边缘
cv2.Canny(image, threshold1, threshold2[, edges[, apertureSize[, L2gradient]]]) -> edges
参数:image-8位输入图像
threshold1-设置的低阈值
threshold2-设置的高阈值,一般高低阈值的比例为3:1或者2:1
运行结果如下
如果使用带自定义图像渐变的Canny算法在图像中查找边缘
cv2.Canny(dx, dy, threshold1, threshold2[, edges[, L2gradient]]) -> edges
参数:dx-输入图像的x导数(x导数满足16位,选择CV_16SC1或CV_16SC3)
dy-输入图像的y导数(y导数满足16位,选择CV_16SC1或CV_16SC3)
threshold1-设置的低阈值
threshold2-设置的高阈值,一般高低阈值的比例为3:1或者2:1