cv2.Canny源码
时间: 2023-05-25 08:02:30 浏览: 285
cv2.Canny函数的源码实现是基于C++实现的,其核心部分是一系列C++函数的调用。
以下是cv2.Canny函数的处理流程:
1. 如果输入图像不是灰度图像,则转换为灰度图像。
2. 根据高斯滤波器的指定参数,对灰度图像进行高斯滤波。
3. 计算图像中每个像素的梯度幅值和方向。
4. 对梯度幅值进行非最大值抑制,即在每个像素的梯度方向上查找最大值并抑制其他值。
5. 通过双阈值算法将像素区分为边缘和非边缘。
6. 通过连接边缘像素,形成单个的、完整的边缘线。
以下是cv2.Canny函数的主要代码:
1. 转换至灰度图像。
```
if img.ndim == 3:
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
else:
gray = img
```
2. 高斯滤波。
```
blur = cv2.GaussianBlur(gray, (kernel_size, kernel_size), sigma)
```
3. 计算梯度幅值和方向。
```
dx = cv2.Sobel(blur, cv2.CV_64F, 1, 0, ksize=3)
dy = cv2.Sobel(blur, cv2.CV_64F, 0, 1, ksize=3)
mag = np.sqrt(dx**2 + dy**2)
angles = np.arctan2(dy, dx) * 180 / np.pi
```
4. 非最大值抑制。
```
grad_mag_sup = np.zeros_like(mag)
for i in range(1, grad_mag.shape[0]-1):
for j in range(1, grad_mag.shape[1]-1):
if (0 <= angles[i,j]<22.5) or (157.5<=angles[i,j]<=180):
grad_mag_sup[i,j] = gradient[i,j] if (gradient[i,j] >= gradient[i-1,j]) and (gradient[i,j] >= gradient[i+1,j]) else 0
elif (22.5<=angles[i,j]<67.5):
grad_mag_sup[i,j] = gradient[i,j] if (gradient[i,j] >= gradient[i-1,j-1]) and (gradient[i,j] >= gradient[i+1,j+1]) else 0
elif (67.5<=angles[i,j]<112.5):
grad_mag_sup[i,j] = gradient[i,j] if (gradient[i,j] >= gradient[i,j-1]) and (gradient[i,j] >= gradient[i,j+1]) else 0
else:
grad_mag_sup[i,j] = gradient[i,j] if (gradient[i,j] >= gradient[i-1,j+1]) and (gradient[i,j] >= gradient[i+1,j-1]) else 0
```
5. 双阈值算法。
```
low_threshold = 0.05*grad_mag_sup.max()
high_threshold = 0.09*grad_mag_sup.max()
edge = np.zeros_like(grad_mag_sup, dtype=np.uint8)
edge[grad_mag_sup >= high_threshold] = 255
edge[(grad_mag_sup >= low_threshold) & (grad_mag_sup < high_threshold)] = 128
```
6. 边缘连接。
```
def trace_edge(i, j):
edge[i, j] = 255
for x, y in neighbors[i:i+3, j:j+3]:
if edge[x, y] == 128:
trace_edge(x, y)
for i in range(1, edge.shape[0]-1):
for j in range(1, edge.shape[1]-1):
if edge[i, j] == 255:
trace_edge(i, j)
```
完整的cv2.Canny函数源码可以在OpenCV的官方库中找到。
阅读全文