拉普拉斯检测算子结合在一起进行边缘检测的方法:先对图像进行平滑,然后再用Laplacian算子检测边缘。
因为卷积具有结合律,拉氏变换其实也是对模板的卷积。
h(x,y)的拉氏变换:
所以,就变成了图像跟LoG的卷积,其实可以把LoG当成滤波器。
代码如下(示例):
def generate_LoG_filter(size, sigma):
# 计算中心位置
center = size // 2
# 生成网格 meshgrid生成一个二维数组(x,y)
x, y = np.meshgrid(np.arange(size), np.arange(size))
# 计算每个像素到中心位置的距离的平方
r_squared = (x - center) ** 2 + (y - center) ** 2
# 生成高斯权值和模板
gaussian = 1.0 / (2 * np.pi * sigma ** 2) * np.exp(-r_squared / (2 * sigma ** 2))
# 生成拉普拉斯算子模板
laplacian = (r_squared - 2 * sigma ** 2) / (sigma ** 4) * gaussian
# 将模板归一化
laplacian = laplacian/np.sum(laplacian)
return laplacian
代码如下(示例):
def my_LoG(img, kernel_size, sigma):
# 创建LoG滤波器
kernel = generate_LoG_filter(kernel_size, sigma)
# 图像卷积
filtered_img = img_filter2D.my_filter2D(img,kernel)
return filtered_img
#边缘判断
# Marr边缘检测
def marr_edge_detection(img, threshold):
# 对图像进行LoG滤波
filtered_img = my_LoG(img, 5, 1)
# 查找零交叉点
zero_crossing = np.zeros_like(filtered_img)
rows, cols = filtered_img.shape
for i in range(1, rows - 1):
for j in range(1, cols - 1):
neighbors = [filtered_img[i+1, j], filtered_img[i-1, j], filtered_img[i, j+1], filtered_img[i, j-1],
filtered_img[i+1, j+1], filtered_img[i-1, j-1], filtered_img[i+1, j-1], filtered_img[i-1, j+1]]
if filtered_img[i, j] == 0:
if (np.sign(neighbors) != np.sign(filtered_img[i, j])).any():
zero_crossing[i, j] = 255
elif (np.sign(neighbors) != np.sign(filtered_img[i, j])).sum() > 2:
zero_crossing[i, j] = 255
# 将像素值大于阈值的点作为边缘点输出
threshold_img = np.zeros_like(filtered_img)
threshold_img[filtered_img > threshold] = 255
# 将零交叉点和大于阈值的点作为边缘点合并输出
edge_img = np.zeros_like(filtered_img)
edge_img[(zero_crossing == 255) | (threshold_img == 255)] = 255
return edge_img
#打印
# 读取图像并进行Marr边缘检测
img = cv2.imread('lena.bmp', 0)
# 创建一个2x3的子图
fig, axs = plt.subplots(nrows=2, ncols=3, figsize=(10, 8))
# 设置不同的阈值参数
thresholds = [10, 30, 50, 70, 90, 110]
# 循环绘制每组Marr边缘检测结果
for i, ax in enumerate(axs.flat):
if i == 0:
# 绘制原图
ax.imshow(img, cmap='gray')
ax.set_title('Original Image')
ax.axis('off')
else:
# 进行Marr边缘检测并绘制结果
edge_img = marr_edge_detection(img, thresholds[i-1])
title = f'threshold={thresholds[i-1]}'
ax.imshow(edge_img, cmap='gray')
ax.set_title(title)
ax.axis('off')
plt.show()