【发布时间】:2011-07-07 03:21:42
【问题描述】:
我正在尝试去除这张图片中的正弦噪声:
这是它的 DFT 谱(在应用对数和任意强度缩放之后):
我已经有一个 Butterworth 过滤器可应用于此图像。它将消除中频峰值。加载后,我注意将其从 [0..255] 缩放到 [0..1.0]。这是过滤器:
结果不是很好:
我的问题:
- 为什么图像中仍然存在大量噪点?
- 为什么结果比原始图像暗?过滤器显然没有触及 DC 项,所以我希望平均强度是相同的。
- 为什么过滤器只去除一些峰?它来自教科书,所以我倾向于相信它是正确的,但光谱中还有其他峰值——它们也是噪音的一部分吗?我尝试使用同心滤镜去除它们,但效果不佳,而且图像变暗,无法辨认。
我从 Gonzalez 和 Woods 的书 Digital Image Processing 中拍摄了图像(裁剪)和过滤器。在他们的例子中,周期性噪声被过滤完全去除,图像的平均强度保持不变。
我的加载图片和滤镜、DFT、滤波、IDFT的源码如下:
import cv
def unshift_crop(comp, width, height):
result = cv.CreateImage((width, height), cv.IPL_DEPTH_8U, 1)
for x in range(height):
for y in range(width):
real, _, _, _ = cv.Get2D(comp, x, y)
real = int(real) * ((-1)**(x+y))
cv.Set2D(result, x, y, cv.Scalar(real))
return result
def load_filter(fname):
loaded = cv.LoadImage(fname, cv.CV_LOAD_IMAGE_GRAYSCALE)
flt = cv.CreateImage(cv.GetSize(loaded), cv.IPL_DEPTH_32F, 2)
width, height = cv.GetSize(loaded)
for i in range(width*height):
px, _, _, _ = cv.Get1D(loaded, i)
#cv.Set1D(flt, i, cv.Scalar(px/255.0, 0))
cv.Set1D(flt, i, cv.Scalar(px/255.0, px/255.0))
return flt
if __name__ == '__main__':
import sys
fname, filt_name, ofname = sys.argv[1:]
img = cv.LoadImage(fname, cv.CV_LOAD_IMAGE_GRAYSCALE)
width, height = cv.GetSize(img)
src = cv.CreateImage((width*2, height*2), cv.IPL_DEPTH_32F, 2)
dst = cv.CreateImage((width*2, height*2), cv.IPL_DEPTH_32F, 2)
cv.SetZero(src)
for x in range(height):
for y in range(width):
px, _, _, _ = cv.Get2D(img, x, y)
px = float(px) * ((-1) ** (x+y))
cv.Set2D(src, x, y, cv.Scalar(px, 0))
cv.DFT(src, dst, cv.CV_DXT_FORWARD)
flt = load_filter(filt_name)
cv.Mul(dst, flt, src)
cv.DFT(src, dst, cv.CV_DXT_INV_SCALE)
result = unshift_crop(dst, width, height)
cv.SaveImage(ofname, result)
编辑
原始源代码中存在一个错误,其中过滤器虚构组件加载为零。这就是导致结果图像看起来比实际更暗的原因。我已修复此问题并评论了相关行。
使用@0x69 提供的固定源和过滤器(是的,我知道这不是真正的巴特沃斯过滤器,但在这个阶段我很乐意尝试任何东西),结果如下:
比我开始时要好,但仍然没有我希望的那么好。谁能打败这个?我怀疑添加更多的凹槽以消除剩余的峰值可能会有一些好处。
编辑 2
我已经联系了作者。这是他们的回应:
问题是使用的图像 实验是浮点数, 而书中显示的那个(和 中提供的原件 下载)为 8 位。这是 打印等所需的。
为了重复实验, 你必须从无噪音开始 图像,然后添加自己的噪音 它。
【问题讨论】:
-
+1 以获得一个完整的解释清楚的问题
-
为什么不显示过滤后图像的dft?
-
@highBandWidth 因为从过滤器和输入图像的 DFT(通过乘法)确定它很简单。
标签: python image-processing opencv