Idea
opencv 中 有个实现 高斯滤波 的接口,如下:
cv2.GaussianBlur(src, ksize, sigmaX, dst=None, sigmaY=None, borderType=None)
在做项目的过程中,我发现如果根据 像素点 相对整张图片 的位置 设计 不同的 滤波核大小(即参数 ksize),就可以灵活地对整张图片实现 动态 高斯滤波 了。
具体滤波核大小计算公式如下:
size = int(k1*x + k2*y + b) * 2 + 1
Note : 注意保证 输出结果 为 整型奇数,因为 参数 ksize 只 接受 整型奇数输入。
由于我的图片大小是 600×424×3 ,所以我的 k1,k2,b 取值如下:
k1,k2,b=⎧⎩⎨⎪⎪0,0.012,00.009,0,00.0053,0.0053,0垂直高斯;水平高斯;对角高斯.
Demo
原图像:
水平动态高斯滤波:
垂直动态高斯滤波:
Code
以下代码中,关于 “对角动态高斯滤波(diagonal gaussian)” 的代码段有问题,所以被我注释掉了。
因为不能对单元素单独进行高斯滤波,所以会报错。具体该怎么解决,我也一时没想到。
# coding=utf-8
import numpy as np
import cv2
def kernel_size(x, y, type):
if type == "vertical":
k1, k2, b = 0, 0.012, 0
elif type == "horizontal":
k1, k2, b = 0.009, 0, 0
elif type == "diagonal":
k1, k2, b = 0.0053, 0.0053, 0
else:
k1, k2, b = 0, 0, 11
size = int(k1*x + k2*y + b) * 2 + 1
return size
def range_limit(img):
img *= (img>0)
img = img * (img<=255) + 255 * (img>255)
img = img.astype(np.uint8)
return img
def dynamic_gaussian(img):
h, w, c = np.shape(img)
sigma = 2
# gs_v: vertical gaussian, 垂直高斯
# gs_h: horizontal gaussian, 水平高斯
# gs_d: diagonal gaussian, 对角高斯
gs_v, gs_h, gs_d = img.copy(), img.copy(), img.copy()
for i in range(h):
k_size = kernel_size(w, i, "vertical")
gs_v[i, :, :] = cv2.GaussianBlur(gs_v[i, :, :], (k_size, k_size), sigma)
print(i, k_size)
for j in range(w):
k_size = kernel_size(j, h, "horizontal")
gs_h[:, j, :] = cv2.GaussianBlur(gs_h[:, j, :], (k_size, k_size), sigma)
print(j, k_size)
# # 报错:
# for i in range(h):
# for j in range(w):
# k_size = kernel_size(i, j, "diagonal")
# gs_d[i, j, :] = cv2.GaussianBlur(gs_d[i, j, :], (k_size, k_size), sigma)
# print(i, j, k_size)
return gs_v, gs_h, gs_d
def main():
img_path = "./girl.jpg"
img = cv2.imread(img_path)
gs_v, gs_h, gs_d = dynamic_gaussian(img)
cv2.imwrite("./gs_v.jpg", gs_v)
cv2.imwrite("./gs_h.jpg", gs_h)
cv2.imwrite("./gs_d.jpg", gs_d)
if __name__ == "__main__":
main()