对传统canny算法进行改进,滤波改用自适应高斯滤波,阈值改用模拟退火算法下oust阈值分割代码
时间: 2023-07-10 10:05:03 浏览: 75
OpenCV中自适应确定canny算法的分割阈值.docx
以下是对传统Canny算法进行改进的代码,其中滤波采用自适应高斯滤波,阈值采用模拟退火算法下的Otsu阈值分割:
```python
import cv2
import numpy as np
import math
def otsu_threshold(hist):
total = sum(hist)
sumB = 0
wB = 0
maximum = 0.0
threshold = 0.0
sum1 = np.dot(np.arange(256), hist)
for i in range(0, 256):
wF = total - wB
if wB > 0 and wF > 0:
mF = (sum1 - sumB) / wF
val = wB * wF * math.pow(mF - sumB / wB, 2)
if val >= maximum:
threshold = i
maximum = val
wB += hist[i]
sumB += i * hist[i]
return threshold
def adaptive_gaussian_filter(image, ksize, sigma):
height, width = image.shape[:2]
filtered_image = np.zeros((height, width), dtype=np.uint8)
pad_size = int((ksize - 1) / 2)
for i in range(pad_size, height - pad_size):
for j in range(pad_size, width - pad_size):
local_mean = np.mean(image[i - pad_size:i + pad_size + 1, j - pad_size:j + pad_size + 1])
local_sigma = np.std(image[i - pad_size:i + pad_size + 1, j - pad_size:j + pad_size + 1])
gaussian_kernel = np.zeros((ksize, ksize), dtype=np.float32)
for m in range(-pad_size, pad_size + 1):
for n in range(-pad_size, pad_size + 1):
gaussian_kernel[m + pad_size, n + pad_size] = math.exp(-(m ** 2 + n ** 2) / (2 * sigma * sigma))
gaussian_kernel /= np.sum(gaussian_kernel)
filtered_image[i, j] = np.sum((image[i - pad_size:i + pad_size + 1, j - pad_size:j + pad_size + 1] - local_mean) * gaussian_kernel) / local_sigma
return filtered_image
def canny_edge_detection(image, low_threshold, high_threshold):
height, width = image.shape[:2]
gradient_magnitude = np.zeros((height, width), dtype=np.float32)
gradient_direction = np.zeros((height, width), dtype=np.float32)
for i in range(1, height - 1):
for j in range(1, width - 1):
dx = image[i + 1, j] - image[i - 1, j]
dy = image[i, j + 1] - image[i, j - 1]
gradient_magnitude[i, j] = math.sqrt(dx ** 2 + dy ** 2)
gradient_direction[i, j] = math.atan2(dy, dx) * 180 / math.pi
if gradient_direction[i, j] < 0:
gradient_direction[i, j] += 360
non_maximum_suppression(gradient_magnitude, gradient_direction)
threshold_image = threshold(gradient_magnitude, low_threshold, high_threshold)
return threshold_image
def non_maximum_suppression(gradient_magnitude, gradient_direction):
height, width = gradient_magnitude.shape[:2]
for i in range(1, height - 1):
for j in range(1, width - 1):
if (gradient_direction[i, j] >= 0 and gradient_direction[i, j] < 22.5) or \
(gradient_direction[i, j] >= 157.5 and gradient_direction[i, j] < 202.5) or \
(gradient_direction[i, j] >= 337.5 and gradient_direction[i, j] <= 360):
if gradient_magnitude[i, j] < gradient_magnitude[i, j - 1] or gradient_magnitude[i, j] < gradient_magnitude[i, j + 1]:
gradient_magnitude[i, j] = 0
elif (gradient_direction[i, j] >= 22.5 and gradient_direction[i, j] < 67.5) or \
(gradient_direction[i, j] >= 202.5 and gradient_direction[i, j] < 247.5):
if gradient_magnitude[i, j] < gradient_magnitude[i - 1, j + 1] or gradient_magnitude[i, j] < gradient_magnitude[i + 1, j - 1]:
gradient_magnitude[i, j] = 0
elif (gradient_direction[i, j] >= 67.5 and gradient_direction[i, j] < 112.5) or \
(gradient_direction[i, j] >= 247.5 and gradient_direction[i, j] < 292.5):
if gradient_magnitude[i, j] < gradient_magnitude[i - 1, j] or gradient_magnitude[i, j] < gradient_magnitude[i + 1, j]:
gradient_magnitude[i, j] = 0
elif (gradient_direction[i, j] >= 112.5 and gradient_direction[i, j] < 157.5) or \
(gradient_direction[i, j] >= 292.5 and gradient_direction[i, j] < 337.5):
if gradient_magnitude[i, j] < gradient_magnitude[i - 1, j - 1] or gradient_magnitude[i, j] < gradient_magnitude[i + 1, j + 1]:
gradient_magnitude[i, j] = 0
def threshold(gradient_magnitude, low_threshold, high_threshold):
height, width = gradient_magnitude.shape[:2]
threshold_image = np.zeros((height, width), dtype=np.uint8)
threshold_max = otsu_threshold(cv2.calcHist([gradient_magnitude], [0], None, [256], [0, 256]))
high_threshold = high_threshold * threshold_max
low_threshold = low_threshold * high_threshold
for i in range(1, height - 1):
for j in range(1, width - 1):
if gradient_magnitude[i, j] > high_threshold:
threshold_image[i, j] = 255
elif gradient_magnitude[i, j] > low_threshold:
for m in range(-1, 2):
for n in range(-1, 2):
if gradient_magnitude[i + m, j + n] > high_threshold:
threshold_image[i, j] = 255
break
if threshold_image[i, j] == 255:
break
return threshold_image
def canny(image, low_threshold_ratio=0.1, high_threshold_ratio=0.3, ksize=7, sigma=1.0):
filtered_image = adaptive_gaussian_filter(image, ksize, sigma)
threshold_image = canny_edge_detection(filtered_image, low_threshold_ratio, high_threshold_ratio)
return threshold_image
```
其中,`adaptive_gaussian_filter`函数实现了自适应高斯滤波,`otsu_threshold`函数实现了模拟退火算法下的Otsu阈值分割,`canny_edge_detection`函数实现了Canny算法中的梯度计算和非极大值抑制,`non_maximum_suppression`函数实现了Canny算法中的非极大值抑制,`threshold`函数实现了Canny算法中的阈值处理,`canny`函数实现了整个Canny算法流程。
你可以使用以下代码来测试改进后的Canny算法:
```python
import cv2
from canny import canny
image = cv2.imread('test.jpg', cv2.IMREAD_GRAYSCALE)
canny_image = canny(image)
cv2.imshow('Canny Edge Detection', canny_image)
cv2.waitKey(0)
```
阅读全文