python - 我们如何从输入图像中去除棋盘状噪声
解决方案
这是在 Python/OpenCV 中使用陷波滤波的一种方法。
- 将输入读取为灰度
- 对复实部和虚部进行 DFT
- 将 DC 点移到中心
- 将实部和虚部转换为幅度和相位
- 从幅度计算频谱图像
- 对光谱图像进行阈值化以提取与规则棋盘格图案对应的网格线
- 使中心 DC 点周围的白色区域变黑
- 反转蒙版
- 将幅度乘以掩码
- 将新幅度和旧相位转换为实部和虚部
- 结合实部和虚部
- 将 DC 点移到左上角
- 进行 DIFT 并转换为 8 位范围作为陷波滤波器结果
- 拉伸动态范围以提高可见度
- 保存结果
输入:
import numpy as np
import cv2
import skimage.exposure
# read input as grayscale
# opencv fft only works on grayscale
img = cv2.imread('checkerboard_noise.jpg', 0)
hh, ww = img.shape[:2]
# convert image to floats and do dft saving as complex output
dft = cv2.dft(np.float32(img), flags = cv2.DFT_COMPLEX_OUTPUT)
# apply shift of origin from upper left corner to center of image
dft_shift = np.fft.fftshift(dft)
# extract magnitude and phase images
mag, phase = cv2.cartToPolar(dft_shift[:,:,0], dft_shift[:,:,1])
# get spectrum for viewing only
spec = (np.log(mag) / 20)
# threshold spectrum as mask
mask = cv2.threshold(spec, 0.5, 1, cv2.THRESH_BINARY)[1]
# blacken out center DC region from mask
cx = ww // 2
cy = hh // 2
mask = cv2.circle(mask, (cx,cy), 10, 0, -1)
# invert mask
mask = 1 - mask
# apply mask to magnitude image
mag_notch = mask*mag
# convert magnitude and phase into cartesian real and imaginary components
real, imag = cv2.polarToCart(mag_notch, phase)
# combine cartesian components into one complex image
complex = cv2.merge([real, imag])
# shift origin from center to upper left corner
complex_ishift = np.fft.ifftshift(complex)
# do idft with normalization saving as real output
img_notch = cv2.idft(complex_ishift, flags=cv2.DFT_SCALE+cv2.DFT_REAL_OUTPUT)
img_notch = img_notch.clip(0,255).astype(np.uint8)
# stretch contrast
img_notch_stretched = skimage.exposure.rescale_intensity(img_notch, in_range=(75,150), out_range=(0,255))
# write result to disk
cv2.imwrite("checkerboard_noise_spectrum.png", (255*spec).clip(0,255).astype(np.uint8))
cv2.imwrite("checkerboard_noise_mask.png", (255*mask).clip(0,255).astype(np.uint8))
cv2.imwrite("checkerboard_noise_notched.png", img_notch)
cv2.imwrite("checkerboard_noise_notched_stretched.png", img_notch_stretched)
# show results
cv2.imshow("ORIGINAL", img)
cv2.imshow("MAG", mag)
cv2.imshow("PHASE", phase)
cv2.imshow("SPECTRUM", spec)
cv2.imshow("MASK", mask)
cv2.imshow("NOTCH", img_notch)
cv2.imshow("NOTCH_STRETCHED", img_notch_stretched)
cv2.waitKey(0)
cv2.destroyAllWindows()
光谱:
面具:
缺口滤波器结果:
缺口滤波器对比度增强:
推荐阅读
- bash - 用变量替换命令会导致找不到命令?
- go - 是服务还是入口点应该将请求数据转换为域模型
- database - 为什么我的 SnappyData 集群每天遇到一次缓慢的查询
- php - PHP返回错误500
- c - 检测 32 位或 64 位的一个字节中的 ascii 字符
- segmentation-fault - PHP 7 试图破坏从 C 扩展获得的资源会产生段错误
- javascript - jquery - 根据其他元素的CSS属性控制元素的CSS属性
- functional-programming - 哪种方法更接近函数式编程范式来查找多个总数?
- python - 如何在字典中打印递增顺序?
- laravel - 如何动态加载/渲染 Laravel Collective 表单?