使用Python编写Canny 算法,要求高斯滤波与sobel算法都要手写实现,不能使用现有的函数
时间: 2024-05-07 13:15:40 浏览: 119
canny 算法 源代码
以下是使用Python编写Canny算法的示例代码。该代码包括手写的高斯滤波和Sobel算法实现。
```python
import numpy as np
import cv2
def gaussian_kernel(size, sigma):
"""
生成高斯卷积核
"""
kernel = np.zeros((size, size))
center = size // 2
for i in range(size):
for j in range(size):
x = i - center
y = j - center
kernel[i, j] = np.exp(-(x**2 + y**2) / (2 * sigma**2))
kernel /= (2 * np.pi * sigma**2)
return kernel
def convolution(image, kernel):
"""
实现卷积操作
"""
m, n = image.shape
ksize = kernel.shape[0]
pad = ksize // 2
padded_image = np.pad(image, pad, mode='edge')
result = np.zeros((m, n))
for i in range(pad, m + pad):
for j in range(pad, n + pad):
patch = padded_image[i-pad:i+pad+1, j-pad:j+pad+1]
result[i-pad, j-pad] = np.sum(patch * kernel)
return result
def sobel(image):
"""
计算Sobel算子
"""
kernel_x = np.array([[-1, 0, 1], [-2, 0, 2], [-1, 0, 1]])
kernel_y = np.array([[-1, -2, -1], [0, 0, 0], [1, 2, 1]])
dx = convolution(image, kernel_x)
dy = convolution(image, kernel_y)
magnitude = np.sqrt(dx**2 + dy**2)
orientation = np.arctan2(dy, dx)
return magnitude, orientation
def non_maximum_suppression(magnitude, orientation):
"""
非极大值抑制
"""
m, n = magnitude.shape
result = np.zeros((m, n))
for i in range(1, m-1):
for j in range(1, n-1):
angle = orientation[i, j] * 180 / np.pi
if angle < 0:
angle += 180
if (0 <= angle < 22.5) or (157.5 <= angle < 180):
if magnitude[i, j] >= magnitude[i, j-1] and magnitude[i, j] >= magnitude[i, j+1]:
result[i, j] = magnitude[i, j]
elif (22.5 <= angle < 67.5):
if magnitude[i, j] >= magnitude[i-1, j-1] and magnitude[i, j] >= magnitude[i+1, j+1]:
result[i, j] = magnitude[i, j]
elif (67.5 <= angle < 112.5):
if magnitude[i, j] >= magnitude[i-1, j] and magnitude[i, j] >= magnitude[i+1, j]:
result[i, j] = magnitude[i, j]
elif (112.5 <= angle < 157.5):
if magnitude[i, j] >= magnitude[i-1, j+1] and magnitude[i, j] >= magnitude[i+1, j-1]:
result[i, j] = magnitude[i, j]
return result
def thresholding(image, low_threshold, high_threshold):
"""
阈值处理
"""
m, n = image.shape
result = np.zeros((m, n))
weak = 50
strong = 255
strong_i, strong_j = np.where(image >= high_threshold)
weak_i, weak_j = np.where((image >= low_threshold) & (image < high_threshold))
result[strong_i, strong_j] = strong
result[weak_i, weak_j] = weak
return result
def hysteresis_thresholding(image):
"""
双阈值处理
"""
weak = 50
strong = 255
m, n = image.shape
for i in range(1, m-1):
for j in range(1, n-1):
if image[i, j] == weak:
if (image[i-1:i+2, j-1:j+2] == strong).any():
image[i, j] = strong
else:
image[i, j] = 0
return image
def canny(image, low_threshold, high_threshold, sigma=1.4):
"""
Canny算法
"""
kernel_size = 5
kernel = gaussian_kernel(kernel_size, sigma)
smoothed = convolution(image, kernel)
magnitude, orientation = sobel(smoothed)
suppressed = non_maximum_suppression(magnitude, orientation)
thresholded = thresholding(suppressed, low_threshold, high_threshold)
result = hysteresis_thresholding(thresholded)
return result
# 测试代码
image = cv2.imread('lena.png', cv2.IMREAD_GRAYSCALE)
result = canny(image, 50, 150)
cv2.imshow('input', image)
cv2.imshow('output', result)
cv2.waitKey()
cv2.destroyAllWindows()
```
在上述代码中,我们首先定义了一个函数 `gaussian_kernel(size, sigma)`,用于生成高斯卷积核。然后定义了函数 `convolution(image, kernel)`,实现了卷积操作。接下来,我们定义了函数 `sobel(image)`,计算Sobel算子并返回梯度幅值和方向。然后,我们定义了函数 `non_maximum_suppression(magnitude, orientation)`,实现了非极大值抑制。接着,我们定义了函数 `thresholding(image, low_threshold, high_threshold)`,实现阈值处理。最后,我们定义了函数 `hysteresis_thresholding(image)`,实现双阈值处理。最终,我们将所有这些函数组合起来,实现了完整的Canny算法。
在测试代码中,我们使用了OpenCV库读取了一张灰度图像。然后,我们调用了 `canny(image, low_threshold, high_threshold)` 函数,并将结果显示在屏幕上。在这个例子中,我们将低阈值设为50,高阈值设为150。你可以调整这些参数,改变Canny算法的表现。
阅读全文