使用python编写canny算法 不能调用opencv库函数
时间: 2024-05-09 17:18:37 浏览: 109
以下是使用Python编写Canny算法的示例代码:
```python
import numpy as np
import math
def gaussian_kernel(size, sigma):
"""
生成高斯核
"""
kernel = np.zeros((size, size))
for i in range(size):
for j in range(size):
kernel[i][j] = math.exp(-((i-(size-1)/2)**2+(j-(size-1)/2)**2)/(2*sigma**2))/(2*math.pi*sigma**2)
return kernel/np.sum(kernel)
def sobel_filter(image):
"""
使用Sobel算子计算梯度幅值和方向
"""
sobel_x = np.array([[-1, 0, 1], [-2, 0, 2], [-1, 0, 1]])
sobel_y = np.array([[-1, -2, -1], [0, 0, 0], [1, 2, 1]])
height, width = image.shape
gradient_x = np.zeros((height, width))
gradient_y = np.zeros((height, width))
for i in range(1, height-1):
for j in range(1, width-1):
gradient_x[i][j] = np.sum(np.multiply(sobel_x, image[i-1:i+2, j-1:j+2]))
gradient_y[i][j] = np.sum(np.multiply(sobel_y, image[i-1:i+2, j-1:j+2]))
gradient_magnitude = np.sqrt(np.square(gradient_x) + np.square(gradient_y))
gradient_direction = np.arctan2(gradient_y, gradient_x)
return gradient_magnitude, gradient_direction
def non_maximum_suppression(gradient_magnitude, gradient_direction):
"""
非极大值抑制
"""
height, width = gradient_magnitude.shape
suppressed = np.zeros((height, width))
for i in range(1, height-1):
for j in range(1, width-1):
theta = gradient_direction[i][j]
if (theta < 0):
theta += math.pi
if (theta >= math.pi/8 and theta < 3*math.pi/8):
q = gradient_magnitude[i+1][j]
r = gradient_magnitude[i-1][j]
elif (theta >= 3*math.pi/8 and theta < 5*math.pi/8):
q = gradient_magnitude[i+1][j-1]
r = gradient_magnitude[i-1][j+1]
elif (theta >= 5*math.pi/8 and theta < 7*math.pi/8):
q = gradient_magnitude[i][j-1]
r = gradient_magnitude[i][j+1]
else:
q = gradient_magnitude[i+1][j+1]
r = gradient_magnitude[i-1][j-1]
p = gradient_magnitude[i][j]
if (p >= q and p >= r):
suppressed[i][j] = p
else:
suppressed[i][j] = 0
return suppressed
def double_thresholding(suppressed, low_threshold_ratio, high_threshold_ratio):
"""
双阈值法
"""
high_threshold = np.max(suppressed) * high_threshold_ratio
low_threshold = high_threshold * low_threshold_ratio
height, width = suppressed.shape
strong_edges = np.zeros((height, width), dtype=np.int32)
weak_edges = np.zeros((height, width), dtype=np.int32)
strong_edges[suppressed >= high_threshold] = 1
weak_edges[(suppressed < high_threshold) & (suppressed >= low_threshold)] = 1
return strong_edges, weak_edges
def edge_tracking(strong_edges, weak_edges):
"""
边缘跟踪
"""
height, width = strong_edges.shape
edges = np.zeros((height, width), dtype=np.int32)
for i in range(1, height-1):
for j in range(1, width-1):
if (strong_edges[i][j] != 0):
edges[i][j] = 1
elif (weak_edges[i][j] != 0):
if ((strong_edges[i-1:i+2, j-1:j+2] != 0).any()):
edges[i][j] = 1
else:
edges[i][j] = 0
return edges
def canny(image, size, sigma, low_threshold_ratio, high_threshold_ratio):
"""
Canny算法
"""
kernel = gaussian_kernel(size, sigma)
smoothed = np.zeros(image.shape)
height, width = image.shape
for i in range(size//2, height-size//2):
for j in range(size//2, width-size//2):
smoothed[i][j] = np.sum(np.multiply(kernel, image[i-size//2:i+size//2+1, j-size//2:j+size//2+1]))
gradient_magnitude, gradient_direction = sobel_filter(smoothed)
suppressed = non_maximum_suppression(gradient_magnitude, gradient_direction)
strong_edges, weak_edges = double_thresholding(suppressed, low_threshold_ratio, high_threshold_ratio)
edges = edge_tracking(strong_edges, weak_edges)
return edges
```
使用示例:
```python
import cv2
# 读取图像
image = cv2.imread('image.jpg', cv2.IMREAD_GRAYSCALE)
# 调用Canny算法
edges = canny(image, 5, 1, 0.1, 0.3)
# 显示结果
cv2.imshow('edges', edges*255)
cv2.waitKey(0)
cv2.destroyAllWindows()
```
阅读全文