Canny 边缘检测是一种经典的边缘检测算法,由 John F. Canny 在 1986 年提出。它被广泛应用于计算机视觉和图像处理领域,用于检测图像中的边缘。
【原理】
1. 去噪
由于边缘检测非常容易收到图像的噪声影响,第一步使用 5x5 高斯滤波去除图像中的噪声。
2. 寻找图像的亮度梯度
在平滑后(去噪后)的图像利用 Sobel 算子计算图像的 X-, Y- 的一阶导数G ( x ) G(x)G(x)和G ( y ) G(y)G(y),从这两幅图像中我们可以获得边缘的梯度值和方向。
3. 非最大值抑制
获得梯度大小和方向后,对图像进行全扫描,去除可能不构成边缘的任何不需要的像素。在每个像素处,检查像素在梯度方向是否是其领域中的局部最大值。
点A位于垂直边缘上,梯度方向为 A->B, B 和 C 都是梯度方向上的点,如果 A 是邻域内最大的,则保留,否则设置为0。简而言之,会得到一个细的边缘。
4. 滞后阈值
这个阶段决定哪些是真正的边缘,哪些不是。为此,我们需要两个阈值,minVal和maxVal,梯度强度大于maxVal确定是边缘,低于minVal值的边缘点被抛弃,位于这两个值中间的值,根据其邻域点的属性来决定,如果连接到强边缘,则被判定为强边缘,否则丢弃。
上图中,可以看出,尽管C点在maxVal以下,但是与A连接,则C和A都是强边缘点。而B没有强边缘连接,则被丢弃。
import numpy as np
import cv2
from matplotlib import pyplot as plt
img = cv2.imread('messi5.jpg',0)
edges = cv2.Canny(img,100,200)
cv2.imshow("src", img)
cv2.imshow("edge", edges)
cv2.waitKey(0)
cv2.destroyAllWindows()
import numpy as np
import cv2
# 空函数
def nothing(x):
pass
img = cv2.imread('messi5.jpg', 0)
cv2.namedWindow('image')
cv2.createTrackbar('min', 'image', 10, 200, nothing)
cv2.createTrackbar('max', 'image', 0, 255, nothing)
cv2.setTrackbarPos('min', 'image', 50)
cv2.setTrackbarPos('max', 'image', 150)
while(1):
cv2.imshow('image', img)
if cv2.waitKey(2) & 0xFF == 27:
break
minVal = cv2.getTrackbarPos('min', 'image')
maxVal = cv2.getTrackbarPos('max', 'image')
if maxVal < minVal:
maxVal = minVal + 10
cv2.setTrackbarPos('max', 'image', maxVal)
edges = cv2.Canny(img, minVal, maxVal)
cv2.imshow('canny', edges)
cv2.destroyAllWindows()
用Canny方法计算图像的边缘
image: 8位输入图像
edges: 输出的边缘图像, 单通道8位图像,尺寸与原图一致
threshold1: 滞后过程的第一阈值
threshold2: 滞后过程的第二阈值
L2gradient: 一个决定是否需要更好精度的标志,L2gradient=true
dx: 输入图像的16位x导数
dy: 输入图像的16位y导数
Lnton羚通是专注于音视频算法、算力、云平台的高科技人工智能企业。 公司基于视频分析技术、视频智能传输技术、远程监测技术以及智能语音融合技术等, 拥有多款可支持ONVIF、RTSP、GB/T28181等多协议、多路数的音视频智能分析服务器/云平台。