Unnormalized gaussian kernel in cv2



我需要将我的图像与归一化的高斯核进行卷积。当然,我可以自己定义一个函数,但我更喜欢使用cv2函数,它肯定会更有效。

cv2.GaussianBlur是标准化的,显然它没有关闭标准化的选项。

有什么提示吗?

如果你有归一化内核的滤波图像,而非归一化内核的和,你所要做的就是将归一化图像乘以和。

卷积的规则是,您可以切换顺序:
将内核乘以标量,并对图像进行滤波,与对图像进行过滤并将结果乘以标量相同。

以下Python代码演示了该解决方案:

# https://stackoverflow.com/questions/29731726/how-to-calculate-a-gaussian-kernel-matrix-efficiently-in-numpy
def gkern(kernlen=21, nsig=3):
"""Returns a 2D Gaussian kernel."""
x = np.linspace(-nsig, nsig, kernlen+1)
kern1d = np.diff(st.norm.cdf(x))
kern2d = np.outer(kern1d, kern1d)
return (kern2d/kern2d.sum(), kern2d.sum())
# Normalized Gaussian kernel
norm_h, norm_h_sum = gkern(21, 3)
# Simulate un-normalized kernel (sum = 3)
h = norm_h*3
h_sum = h.sum()
# Create random 160x120 image of type float32
img = np.float32(np.random.rand(120, 160))
# Filter with norm_h kernel
img_norm_h = cv2.filter2D(img, -1, norm_h)
# Filter with h kernel
img_h = cv2.filter2D(img, -1, h)
# Multiply img_norm_h by h_sum for getting the same result as img_h
img_norm_h_by_sum = img_norm_h * h_sum
max_abs_diff = np.max(cv2.absdiff(img_h, img_norm_h_by_sum))
print("max_abs_diff = {}".format(max_abs_diff))

注意:
高斯滤波器可以实现为可分离滤波器,因此cv2.GaussianBlur可能比使用cv2.filter2D更有效
cv2.filter2D用于演示原理。


cv2.GaussianBlur:的比较

# Filter and multiply by sum
img_blur = cv2.GaussianBlur(img, (21, 21), 3) * norm_h_sum
# Multiply by sum and filter
img_h = cv2.filter2D(img, -1, norm_h*norm_h_sum)
img_blur_max_abs_diff = np.max(cv2.absdiff(img_blur, img_h))
print("img_blur_max_abs_diff = {}".format(img_blur_max_abs_diff))

相关内容

最新更新