Python 实现双边滤波器
我正试图从论文中实现一个双边过滤器。实现双边滤波器的方程式(来自论文)如下所示:Python 实现双边滤波器,python,algorithm,opencv,computer-vision,dynamic-programming,Python,Algorithm,Opencv,Computer Vision,Dynamic Programming,我正试图从论文中实现一个双边过滤器。实现双边滤波器的方程式(来自论文)如下所示: import cv2 import numpy as np img = cv2.imread("fish.png") # image of width 239 and height 200 bl_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) i = cv2.magnitude( cv2.Sobel(bl_img, cv2.CV_64F, 1, 0, ksi
import cv2
import numpy as np
img = cv2.imread("fish.png")
# image of width 239 and height 200
bl_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
i = cv2.magnitude(
cv2.Sobel(bl_img, cv2.CV_64F, 1, 0, ksize=3),
cv2.Sobel(bl_img, cv2.CV_64F, 0, 1, ksize=3)
)
f = cv2.getGaussianKernel(5, 0.1, cv2.CV_64F)
g = cv2.getGaussianKernel(5, 0.1, cv2.CV_64F)
rows, cols, _ = img.shape
filtered = np.zeros(img.shape, dtype=img.dtype)
for r in range(rows):
for c in range(cols):
ks = []
for index in [-2,-1,1,2]:
if index + c > 0 and index + c < cols-1:
p = img[r][index + c]
s = img[r][c]
i_p = i[index+c]
i_s = i[c]
ks.append(
(f * (p-s)) * (g * (i_p * i_s)) # EQUATION 7
)
ks = np.sum(np.array(ks))
js = []
for index in [-2, -1, 1, 2]:
if index + c > 0 and index + c < cols -1:
p = img[r][index + c]
s = img[r][c]
i_p = i[index+c]
i_s = i[c]
js.append((f * (p-s)) * (g * (i_p * i_s)) * i_p) # EQUATION 6
js = np.sum(np.asarray(js))
js = js / ks
filtered[r][c] = js
cv2.imwrite("f.png", filtered)
据我了解,
- f是高斯滤波器
- g是高斯滤波器
- p是给定图像窗口中的像素
- s是当前像素
- Ip是当前像素处的强度
import cv2
import numpy as np
img = cv2.imread("fish.png")
# image of width 239 and height 200
bl_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
i = cv2.magnitude(
cv2.Sobel(bl_img, cv2.CV_64F, 1, 0, ksize=3),
cv2.Sobel(bl_img, cv2.CV_64F, 0, 1, ksize=3)
)
f = cv2.getGaussianKernel(5, 0.1, cv2.CV_64F)
g = cv2.getGaussianKernel(5, 0.1, cv2.CV_64F)
rows, cols, _ = img.shape
filtered = np.zeros(img.shape, dtype=img.dtype)
for r in range(rows):
for c in range(cols):
ks = []
for index in [-2,-1,1,2]:
if index + c > 0 and index + c < cols-1:
p = img[r][index + c]
s = img[r][c]
i_p = i[index+c]
i_s = i[c]
ks.append(
(f * (p-s)) * (g * (i_p * i_s)) # EQUATION 7
)
ks = np.sum(np.array(ks))
js = []
for index in [-2, -1, 1, 2]:
if index + c > 0 and index + c < cols -1:
p = img[r][index + c]
s = img[r][c]
i_p = i[index+c]
i_s = i[c]
js.append((f * (p-s)) * (g * (i_p * i_s)) * i_p) # EQUATION 6
js = np.sum(np.asarray(js))
js = js / ks
filtered[r][c] = js
cv2.imwrite("f.png", filtered)
导入cv2
将numpy作为np导入
img=cv2.imread(“fish.png”)
#宽度239和高度200的图像
bl\u img=cv2.CVT颜色(img,cv2.COLOR\u BGR2GRAY)
i=cv2.0量级(
cv2.Sobel(bl_img,cv2.CV_64F,1,0,ksize=3),
cv2.Sobel(bl_img,cv2.CV_64F,0,1,ksize=3)
)
f=cv2.getGaussianKernel(5,0.1,cv2.CV_64F)
g=cv2.getGaussianKernel(5,0.1,cv2.CV_64F)
行,列,u=img.shape
过滤=np.零(img.shape,dtype=img.dtype)
对于范围内的r(行):
对于范围内的c(cols):
ks=[]
对于[-2,-1,1,2]中的索引:
如果索引+c>0且索引+c0且索引+c
但是当我运行这段代码时,我得到一个错误,它说:
Traceback (most recent call last):
File "bft.py", line 33, in <module>
(f * (p-s)) * (g * (i_p * i_s))
ValueError: operands could not be broadcast together with shapes (5,3) (5,239)
回溯(最近一次呼叫最后一次):
文件“bft.py”,第33行,在
(f*(p-s))*(g*(i_p*i_s))
ValueError:操作数无法与形状(5,3)(5239)一起广播
我是否错误地实现了这些等式?我遗漏了什么?您的代码存在各种问题。最重要的是,这个等式的解释是错误的。f(p-s)表示在p-s处计算函数f。f是高斯分布。同样地,g。代码的部分如下所示:
weight=gaussian(p-s,sigma\u f)*gaussian(i\u p-i\u s,sigma\u g)
ks.附加(重量)
附加(重量*i_p)
请注意,这两个循环可以合并,这样可以避免重复计算gaussian(x,sigma)
将是一个计算x
处高斯权重的函数。您需要定义两个sigma,sigma\u f
和sigma\u g
,分别是空间sigma和音调sigma
第二个问题是p
和s
的定义。这些是像素的坐标,而不是像素处图像的值i_p
和i_s
是这些位置的图像值p-s
基本上是(r,c)
处的像素与给定邻居之间的空间距离
第三个问题是社区的循环。邻域是所有像素,高斯(p-s,sigma\u f)
是不可忽略的。因此,邻域的大小取决于所选的sigma\u f
。你至少应该把它看作是ceil(2*sigma\u f)
。假设sigma\u f
为2,则希望邻域从-4变为4(9像素)。但是这个邻域是二维的,不像你的代码中那样是一维的。因此需要两个循环:
适用于范围内的ii(-ceil(2*sigma\u f)、ceil(2*sigma\u f)+1):
如果ii+c>0且ii+c0且jj+r
注意,现在,
p-s
是用math.sqrt(ii**2+jj**2)
计算的。但还要注意,高斯函数使用x**2
,因此您可以通过将x**2
传递到高斯函数中来跳过平方根的计算。您的矩阵形状不兼容,不能将一个维数为5,3的矩阵与另一个维数为5的矩阵相乘,239@prhmma你知道对上述方程进行编码的正确方法吗?更改这两行并检查它是否有效ks.append(np.matmul((f*(p-s)).T,(g*(i_p-i_s)))#方程7
和js.append(np.matmul((f*(p-s)).T,(g*(i_p*i_s))*i_p))#方程6
@prhmma不确定这是否是矩阵乘法您需要为高斯核编制索引(或者更好地使用插值)。方程中的f(p-s)意味着在p-s处计算高斯。谢谢您的回答。我正在浏览一个资源,其中描述了实现BF的不同方法。您能给我指一个源吗(或论文)利用邻域的ceil(2*sigma\u f)
实现BF?如果我向算法提供邻域的值,使得总邻域!=ceil(2*sigma\u f)
,这意味着什么?@Amanda:原始论文()提出双边滤波器显示了一个例子,其中截止值接近2西格玛(5西格玛为23个像素)。那里的方程显示无限积分(即整个图像域上的求和)。在2西格玛处截止的概念是,高斯函数将具有非常小的值(对于普通高斯滤波,我总是使用至少3西格玛,但双边滤波不需要那么高的精度)@Amanda:在图像的边缘,你会发现邻域中的像素更少。这很好,因为过滤器是标准化的。你总是除以过滤器权重的总和。如果你的问题与使邻域小于2西格玛有关(降低截止值),则效果是空间高斯形状将被截断,导致非高斯形状