1 边缘检测背景知识
边缘即指图像中连接在一起的像素值发生突变的像素点的集合,故边缘检测则为检测出图像中所有的边缘
1.1 处理方法
根据边缘像素的像素值突变的特性,可以想象到导数是一种即为有效的手段。而在图像中的像素值是离散的值,故在实际边缘检测算法中采用差分来近似导数。
1.2 一阶导数与二阶导数的推导
即一阶导数
而对于二阶导数
又根据一阶导数的差分公式可得
而对于上式,可知其为关于的差分,故可得到关于的差分
综上可知
2 孤立点的检测
2.1 拉普拉斯算子
在图像中,灰度值的变化是双向的——轴与轴。换句话说,在检测边缘像素点时,需要考虑到两个方向的梯度。而拉普拉斯算子在二维空间的表达式为
即为两个方向上的二阶导数之和,而二阶导数相对于一阶导数对于像素点的变化更为敏感,则应用拉普拉斯算子可十分有效的检测到孤立点。当然,也正因为拉普拉斯算子对于变化十分敏感,噪声对其的影响较大。
根据1.2中二阶导数的推导式,可得拉普拉斯算子如下
2.2 检测规则
在点计算的拉普拉斯算子的绝对值大于指定的阈值时(即该点的像素值变化明显),则认为该点为边缘点;对于输出图像中该位置为亮点。否则,为暗点。表达式如下
2.3 空间滤波器
在计算图像中的一阶导数与二阶导数时,空间滤波器是常用计算方法。计算过程为模板系数与在计算点处模板所对应的像素点的灰度值的乘积之和。当模板系数之和为时,表示对于恒定灰度区域计算的模板想要为。
- 为模板系数的个数
- 为模板系数
- 为对于的像素值
例:计算拉普拉斯算子
空间滤波器模板
对应灰度值
两个矩阵元素对应相乘相加则为拉普拉斯算子
2.4 Code
import numpy as np
def point(intput_signal, threshold):
'''
点检测(使用于灰度图)
:param intput_signal: 输入图像
:param threshold: 拉普拉斯算子阈值
:return: 点图像
'''
intput_signal_cp = np.copy(intput_signal) # 输入图像的副本
m, n = intput_signal_cp.shape # 输入图像的尺寸(行、列)
output_signal = np.zeros((m, n)) # 检测点的输出
# 空间滤波模板
filtering_template = np.array([
[0, 1, 0],
[1, -4, 1],
[0, 1, 0]
])
point_matrix = np.zeros((3, 3)) # 矩阵灰度值,用于计算拉普拉斯算子
for i in range(m):
for j in range(n):
# 该像素点灰度值
point_matrix[1, 1] = intput_signal_cp[i, j]
# 该像素点周围的点的灰度值,如若已至边界则视为0
if i - 1 >= 0:
point_matrix[0, 1] = intput_signal_cp[i-1, j]
if i + 1 < m:
point_matrix[2, 1] = intput_signal_cp[i+1, j]
if j - 1 >= 0:
point_matrix[1, 0] = intput_signal_cp[i, j-1]
if j + 1 < n:
point_matrix[1, 2] = intput_signal_cp[i, j+1]
temp = abs(np.sum(point_matrix * filtering_template)) # 拉普拉斯算子值计算
if temp >= threshold:
output_signal[i, j] = 255 # 拉普拉斯算子大于阈值,则为亮点
else:
output_signal[i, j] = 0 #否则为暗点
point_matrix = np.zeros((3, 3)) # 重置,为下一个点做准备
return output_signal