点击上方↑↑↑“OpenCV学堂”关注我
代码演示如何在图像频率域实现卷积模糊与梯度提取
图像频率域
图像处理不仅可以在空间域进行还可以在频率域进行,把空间域的图像开窗卷积形式,变换得到频率域的矩阵点乘形式得到比较好的效果。转换到频率域最常见的是通过傅里叶变换得到图像的频率域表示,处理之后再反变换回去。支持各种卷积处理的效果,比如模糊,梯度提取等,OpenCV中支持傅里叶变换与逆变换的函数分别为
# 傅里叶变换函数
void cv::dft(
InputArray src,
OutputArray dst,
int flags = 0,
int nonzeroRows = 0
)
# 傅里叶逆变换函数
void cv::idft(
InputArray src,
OutputArray dst,
int flags = 0,
int nonzeroRows = 0
)
低通滤波
低通滤波可以看成是卷积模糊在频率域的表现形式,代码实现如下:
def low_pass_filter_demo():
image = cv.imread("D:/images/test1.png", cv.IMREAD_GRAYSCALE)
img_float32 = np.float32(image)
rows, cols = image.shape
crow, ccol = rows//2 , cols//2
# FFT变换
dft = cv.dft(img_float32, flags = cv.DFT_COMPLEX_OUTPUT)
dft_shift = np.fft.fftshift(dft)
# 创建低通滤波器,低频区域为 1, 高频区域为 0
mask = np.zeros((rows, cols, 2), np.uint8)
mask[crow-30:crow+30, ccol-30:ccol+30] = 1
# 滤波
fshift = dft_shift*mask
# 逆变换
f_ishift = np.fft.ifftshift(fshift)
img_back = cv.idft(f_ishift)
img_back = cv.magnitude(img_back[:,:,0],img_back[:,:,1])
cv.normalize(img_back, img_back, 0, 1.0, cv.NORM_MINMAX)
cv.imshow("input", image);
cv.imshow("low-pass-filter", img_back)
cv.imwrite("D:/low_pass.png", np.uint8(img_back*255))
cv.waitKey(0)
cv.destroyAllWindows()
高通滤波
高通滤波可以看成是图像梯度在频率域的计算,代码实现如下:
def high_pass_filter_demo():
image = cv.imread("D:/images/test1.png", cv.IMREAD_GRAYSCALE)
img_float32 = np.float32(image)
rows, cols = image.shape
crow, ccol = rows//2 , cols//2
# FFT变换
dft = cv.dft(img_float32, flags = cv.DFT_COMPLEX_OUTPUT)
dft_shift = np.fft.fftshift(dft)
# 创建高通滤波器,低频区域为 0, 高频区域为 1
mask = np.ones((rows, cols, 2), np.uint8)
mask[crow-30:crow+30, ccol-30:ccol+30] = 0
# 滤波
fshift = dft_shift*mask
# 逆变换
f_ishift = np.fft.ifftshift(fshift)
img_back = cv.idft(f_ishift)
img_back = cv.magnitude(img_back[:,:,0],img_back[:,:,1])
cv.normalize(img_back, img_back, 0, 1.0, cv.NORM_MINMAX)
cv.imshow("input", image);
cv.imshow("high-pass-filter", img_back)
cv.imwrite("D:/high_pass.png", np.uint8(img_back*255))
cv.waitKey(0)
cv.destroyAllWindows()
运行效果如下:
往期精选
告诉大家你 在看