几何平均滤波器与opencv

时间:2018-01-02 18:04:25

标签: python opencv image-processing opencv-python geometric-mean

我想在opencv(python)中对图像应用几何平均滤镜。是否有内置函数或我应该自己实现过滤器?在opencv中实现非线性过滤器的最有效方法是什么?

1 个答案:

答案 0 :(得分:2)

回想一下

的对数身份
log((x1 * x2 * ... * xn)^(1/n)) = (1/n) * (log(x1) + log(x2) + ... + log(xn))

来自Wikipedia

  

几何平均值也可以表示为对数算术平均值的指数。通过使用对数恒等式来变换公式,乘法可以表示为和,并将幂表示为乘法。

这意味着几何平均值可以简单地计算为算术平均值,即图像值的对数的cv2.boxFilter()。然后你只是对结果取幂,你就完成了!

例如,让我们测试手动方法和此方法并检查结果。首先加载图像并定义内核大小:

import cv2
import numpy as np

img = cv2.imread('cameraman.png', cv2.IMREAD_GRAYSCALE).astype(float)
rows, cols = img.shape[:2]
ksize = 5

Cameraman

接下来让我们填充图像并手动计算几何平均值:

padsize = int((ksize-1)/2)
pad_img = cv2.copyMakeBorder(img, *[padsize]*4, cv2.BORDER_DEFAULT)
geomean1 = np.zeros_like(img)
for r in range(rows):
    for c in range(cols):
        geomean1[r, c] = np.prod(pad_img[r:r+ksize, c:c+ksize])**(1/(ksize**2))
geomean1 = np.uint8(geomean1)
cv2.imshow('1', geomean1)
cv2.waitKey()

Geometric mean 1

看起来像我们期待的那样。现在不是这样,如果我们使用对数版本,我们需要做的就是在图像日志上运行盒式过滤器的指数:

geomean2 = np.uint8(np.exp(cv2.boxFilter(np.log(img), -1, (ksize, ksize))))
cv2.imshow('2', geomean2)
cv2.waitKey()

Geometric mean 2

嗯,他们看起来一样。其实我作弊,这是与上面相同的上传图片。但那可以,因为:

print(np.array_equal(geomean1, geomean2))