中值滤波器(Median)
对((x,y))的邻域(通常为(3 imes3)矩阵)进行排序,然后取中值
用途:
- 去噪
公式:
[f(x,y) = median[(x-1,y-1),(x-1,y-1),(x+1,y-1),(x-1,y),(x,y),(x+1,y),(x-1,y+1),(x,y+1),(x+1,y+1)]
]
边界处理方法:
-
不做边界处理(即最外圈保持原来的值)
class MedianTransform(): ''' 中值变换 ''' @staticmethod def transform(mat: np.ndarray) -> np.ndarray: ''' 对原始矩阵进行变换,返回一个Numpy矩阵 ''' rows, cols = mat.shape[0:2] transform_mat = mat.copy() for row in range(1, rows-2): for col in range(1, cols-2): transform_mat[row][col] = np.median( mat[row-1:row+2, col-1:col+2]) # 实测np.median很慢 return transform_mat
-
补充固定值(例如再填充一圈0)
-
填充最近值
效果:
原图:
变换后的图:
拉普拉斯算子(Laplacian)
对((x,y))邻域进行求导
用途:
- 边缘检测
[g(x, y)=left{egin{array}{l}
f(x, y)-
abla^{2} f(x, y) \
f(x, y)+
abla^{2} f(x, y)
end{array}
ight.
]
公式:
[g(x,y)=5f(x, y)-f(x+1, y)-f(x-1, y)-f(x, y+1)-f(x, y-1)
]
边界处理方法:
-
不做处理:
class LaplacianTransform(): ''' 拉普拉斯算子 ''' @staticmethod def transform(mat: np.ndarray) -> np.ndarray: ''' 对原始矩阵进行变换,返回一个Numpy矩阵 ''' convolution = np.asarray( # 定义卷积核 [ [0, -1, 0], [-1, 5, -1], [0, -1, 0] ] ) rows, cols = mat.shape[0:2] transform_mat = mat.copy() for row in range(1, rows-2): for col in range(1, cols-2): transform_mat[row][col] = np.sum(mat[row - 1:row+2, col-1:col+2]*convolution) return transform_mat
原图:
变换后的图:
傅里叶变换(Fourier)
一维傅里叶变换:
[F(u)=frac{1}{M} sum_{x=0}^{M-1} f(x)(cos 2 pi u x / M-j sin 2 pi u x / M)
]
一维傅里叶逆变换:
[f(x)=sum_{u=0}^{M-1} F(u)[cos 2 pi u x / M+j sin 2 pi u x / M]
]
二维傅里叶变换:
[F(u, v)=frac{1}{M N} sum_{x=0}^{M-1} sum_{y=0}^{N-1} f(x, y) e^{-j 2 pi(u x / M+v y / N)}
]
二维傅里叶反变换:
[f(x, y)=sum_{u=0}^{M-1} sum_{v=0}^{N-1} F(u, v) e^{j 2 pi(u x / M+v y / N)}
]
用途:
根据转换后的频谱以及高通(或者低通)滤波器达到边缘检测或者去噪的作用
class FourierTransform():
'''
傅里叶变换
'''
@staticmethod
def transform(mat: np.ndarray) -> np.ndarray:
'''
对原始矩阵进行变换,返回一个Numpy矩阵
'''
dft = cv2.dft(np.float32(mat),flags=cv2.DFT_COMPLEX_OUTPUT)
dft_shift = np.fft.fftshift(dft) # 平移到中心点
transform_mat = 10 * np.log(cv2.magnitude(dft_shift[:, :, 0], dft_shift[:, :, 1])) # 映射至0~255
return transform_mat.astype(np.uint8)
原图:
转换后的频域图: