【发布时间】:2021-10-21 11:42:14
【问题描述】:
我再次向您提出有关过滤器的问题,在这种情况下:双边过滤器。我确实了解它的一般概念,并且我确实阅读了有关该主题的几个资料(包括有关 stackoverflow 的一些问题)。大多数来源使用这个等式来描述这个过程(我认为最初是来自this 来源,但在这一点上我不确定):
用这个表示的“一般”高斯滤波器(只考虑空间)
我已经成功实现的高斯滤波器。它仅适用于灰度图像,双边滤波器(希望如此)也是如此。我知道,这绝不是一个好的表现,但它确实起到了作用。一般来说,我认为我只需将乘法与 G(Ip - Iq) 相加即可使其用作双边滤波器。我现在的问题是: (Ip - Iq) 到底代表什么?或者换一种方式问,我在哪里检索这些值?
我不确定是否需要我的代码,但无论如何这是我的实现。我从this stackoverflow discussion 获取的内核算法。
def gaussfiltering (img = [], kernelsize=3, sigma=1.9):
rows = len(img)
columns = len(img[0])
kernel = gaussian_kernel(kernelsize, sigma)
horizontallyfiltered = iterate_horizontally(kernel, img, rows, columns, len(kernel))
filtered = iterate_vertically(kernel, horizontallyfiltered, rows, columns, len(kernel))
return filtered
def gaussian_kernel(kernel_size=3, sigma=1.9):
x = numpy.linspace(-sigma, sigma, kernel_size+1)
y = st.norm.cdf(x)
kernel = numpy.diff(y)
return((kernel/kernel.sum()))
def iterate_horizontally (kernel=[], img=[], rows=0, columns=0, kernelsize=0):
horizontallyfiltered = img.copy()
for r in range(rows):
for c in range(columns):
halved = int(kernelsize/2)
if ((c - halved) >= 0 and (c + halved) < columns): #is in range for filter
indexOfImage = c - halved
summed = 0.0
for i in range(kernelsize):
summed += img[r][indexOfImage] * kernel[i]
indexOfImage+=1
horizontallyfiltered[r][c]=summed
return horizontallyfiltered
def iterate_vertically (kernel=[], img=[], rows=0, columns=0, kernelsize=0):
verticallyfiltered = img.copy()
for r in range(rows):
for c in range(columns):
halved = int(kernelsize/2)
if ((r - halved) >= 0 and (r + halved) < rows): #is in range for filter
indexOfImage = r - halved
summed = 0.0
for i in range(kernelsize):
summed += img[indexOfImage][c] * kernel[i]
indexOfImage+=1
verticallyfiltered[r][c]=summed
return verticallyfiltered
编辑:
为此,建议一次通过图像运行整个内核,因此我重写了该函数(并且它本身仍然可以进行精细的高斯滤波)。我还添加了一个函数来计算给定 X 的高斯(没有 mu,因为 mu=0),所以我可以将我的结果与 Ip-Iq 的高斯相乘。然而,这会导致整个图像变得非常暗 - 这很有意义,高斯函数对于现在很远的像素返回大约 0 的值,因此许多像素是暗的。所以我显然在这里仍然有问题,并希望你们中的一个人能指出我。我试图复制的高斯函数:
和新代码:
def iterate_entirely (kernel=[], img=[], rows=0, columns=0, kernelsize=0, sigma=1.9):
filtered = img.copy()
for r in range(rows):
for c in range(columns):
halved = int(kernelsize/2)
if ((c - halved) >= 0 and (c + halved) < columns and (r - halved) >= 0 and (r + halved) < rows): #is in range for filter
indexOfImageRows = r - halved
summed = 0.0
for kr in range(kernelsize):
indexOfImageColumns = c - halved
for kc in range (kernelsize):
ipq = int(img[r][c]) - int(img[indexOfImageRows][indexOfImageColumns])
summed += img[indexOfImageRows][indexOfImageColumns] * kernel[kr][kc] * gaussian(ipq, sigma)
indexOfImageColumns+=1
indexOfImageRows+=1
filtered[r][c]=summed
return filtered
def gaussian(x, sigma):
return 1.0/(numpy.sqrt(2.0*numpy.pi)*sigma)*numpy.exp(-numpy.power((x)/sigma, 2.0)/2)
def gaussian_kernel(kernel_size=3, sigma=1.9):
x = numpy.linspace(-sigma, sigma, kernel_size+1)
y = st.norm.cdf(x)
kernel = numpy.diff(y)
kernel2d = numpy.outer(kernel, kernel)
return (kernel2d/kernel2d.sum())
编辑 2:
更多推荐更改,新代码:
def iterate_entirely (kernel=[], img=[], rows=0, columns=0, kernelsize=0, sigma=1.9):
filtered = img.copy()
for r in range(rows):
for c in range(columns):
halved = int(kernelsize/2)
if ((c - halved) >= 0 and (c + halved) < columns and (r - halved) >= 0 and (r + halved) < rows): #is in range for filter
indexOfImageRows = r - halved
summed = 0.0
norm = 0.0
for kr in range(kernelsize):
indexOfImageColumns = c - halved
for kc in range (kernelsize):
ipq = int(img[r][c]) - int(img[indexOfImageRows][indexOfImageColumns])
multiplicator = kernel[kr][kc] * gaussian(ipq, sigma)
summed += img[indexOfImageRows][indexOfImageColumns] * multiplicator
norm += multiplicator
indexOfImageColumns+=1
indexOfImageRows+=1
print (" summed: ", summed, " norm: ", norm, " normed : ", summed/norm)
filtered[r][c]=summed/norm
return filtered
def gaussian(x, sigma):
return numpy.exp(-numpy.power((x)/sigma, 2.0)/2)
【问题讨论】:
-
考虑在dsp.stackexchange.com上提问
-
“这绝不是一个好的表现”:你是什么意思?该滤波器在边缘保持降噪方面非常有效。如果您的意思是处理时间,请与非本地均值过滤器进行比较!
-
有趣的是,您确实实现了高斯滤波器,其中出现了
Iq,但无法找出Ip-Iq。 -
@YvesDaoust 感谢您的回答/ cmets!我对您的实际答案中的澄清做出了反应,所以我不会再在这里这样做了:D 至于性能:是的,我的意思是从时间的角度来看,因为我觉得每个像素迭代两次(每个使用两个 for 循环运行)感觉有点无效。不过,我会研究非本地方式!
-
@CrisLuengo 至于那个,我当然知道我不只是重复(Ip-Iq)。我只是忘了加 G,抱歉。
标签: python image-processing gaussian imagefilter gaussianblur