opencv各种卷积核滤波器

2020-05-26  本文已影响0人  原上的小木屋

高斯滤波

def gaussian_filter(img, K_size=3, sigma=1.3):
    if len(img.shape) == 3:
        H, W, C = img.shape
    else:
        img = np.expand_dims(img, axis=-1)
        H, W, C = img.shape
    print(H,W,C)
    ## Zero padding
    pad = K_size // 2此处是为后面构造一个将整个图像包裹进去的面做准备 注意啊,前面的灰色//2可不是注释,这是python3的真除法的写法,意思是取商
    out = np.zeros((H + pad * 2, W + pad * 2, C), dtype=np.float)//out将img整个包进去,外面还裹着一半的k_size层
    print(out)
    out[pad: pad + H, pad: pad + W] = img.copy().astype(np.float)//out内层与img完全一样,外层为0
    print(out)
    ## prepare Kernel
    K = np.zeros((K_size, K_size), dtype=np.float)//构造卷积核
    for x in range(-pad, -pad + K_size):
        for y in range(-pad, -pad + K_size):
            K[y + pad, x + pad] = np.exp(-(x ** 2 + y ** 2) / (2 * (sigma ** 2)))
    K /= (2 * np.pi * sigma * sigma)
    K /= K.sum()//卷积核归一化
    tmp = out.copy()

    # filtering
    for y in range(H):
        for x in range(W):
            for c in range(C):
                out[pad + y, pad + x, c] = np.sum(K * tmp[y: y + K_size, x: x + K_size, c])//核心运算,重新计算out与img对应位置的加权像素值
    out = np.clip(out, 0, 255)
    out = out[pad: pad + H, pad: pad + W].astype(np.uint8)//重新将out外层的0去掉
    return out

中值滤波

//此处代码与上述高斯卷积核对应起来看
def median_filter(img, K_size=3):
    H, W, C = img.shape
    ## Zero padding
    pad = K_size // 2   注意啊,前面的灰色//2可不是注释,这是python3的真除法的写法,意思是取商
    out = np.zeros((H + pad*2, W + pad*2, C), dtype=np.float)//同样是生成一个长宽均比img大一个K_size的黑色图像
    out[pad:pad+H, pad:pad+W] = img.copy().astype(np.float)//同样是out与img上下对应填值
    tmp = out.copy()
    # filtering
    for y in range(H):
        for x in range(W):
            for c in range(C):
                out[pad+y, pad+x, c] = np.median(tmp[y:y+K_size, x:x+K_size, c])//取中值进行填充,这也就没啥加权的概念了
    out = out[pad:pad+H, pad:pad+W].astype(np.uint8)//同样截取原来的尺寸
    return out

均值滤波

def mean_filter(img, K_size=3):
    H, W, C = img.shape
    # zero padding
    pad = K_size // 2   注意啊,前面的灰色//2可不是注释,这是python3的真除法的写法,意思是取商
    out = np.zeros((H + pad * 2, W + pad * 2, C), dtype=np.float)
    out[pad: pad + H, pad: pad + W] = img.copy().astype(np.float)
    tmp = out.copy()
    # filtering
    for y in range(H):
        for x in range(W):
            for c in range(C):
                out[pad + y, pad + x, c] = np.mean(tmp[y: y + K_size, x: x + K_size, c])//只有这里和中值滤波有一点小小的差别
    out = out[pad: pad + H, pad: pad + W].astype(np.uint8)
    return out

Motion Filter 对角线滤波

def motion_filter(img, K_size=3):
    H, W, C = img.shape
    # Kernel,构造卷积核
    K = np.diag( [1] * K_size ).astype(np.float)
    K /= K_size
    # zero padding
    pad = K_size // 2   注意啊,前面的灰色//2可不是注释,这是python3的真除法的写法,意思是取商
    out = np.zeros((H + pad * 2, W + pad * 2, C), dtype=np.float)
    out[pad: pad + H, pad: pad + W] = img.copy().astype(np.float)
    tmp = out.copy()
    # filtering
    for y in range(H):
        for x in range(W):
            for c in range(C):
                out[pad + y, pad + x, c] = np.sum(K * tmp[y: y + K_size, x: x + K_size, c])
    out = out[pad: pad + H, pad: pad + W].astype(np.uint8)
    return out

MAX-MIN滤波器

def max_min_filter(img, K_size=3):
    H, W = img.shape

    # Zero padding
    pad = K_size // 2    注意啊,前面的灰色//2可不是注释,这是python3的真除法的写法,意思是取商
    out = np.zeros((H + pad * 2, W + pad * 2), dtype=np.float)
    out[pad: pad + H, pad: pad + W] = gray.copy().astype(np.float)
    tmp = out.copy()

    # filtering
    for y in range(H):
        for x in range(W):
            out[pad + y, pad + x] = np.max(tmp[y: y + K_size, x: x + K_size]) - \
                np.min(tmp[y: y + K_size, x: x + K_size])
    out = out[pad: pad + H, pad: pad + W].astype(np.uint8)
    return out

差分滤波器

def different_filter(img, K_size=3):
    H, W, C = img.shape
    # Zero padding
    pad = K_size // 2   注意啊,前面的灰色//2可不是注释,这是python3的真除法的写法,意思是取商
    out = np.zeros((H + pad * 2, W + pad * 2), dtype=np.float)
    out[pad: pad + H, pad: pad + W] = gray.copy().astype(np.float)
    tmp = out.copy()
    out_v = out.copy()
    out_h = out.copy()
    # vertical kernel
    Kv = [[0., -1., 0.],[0., 1., 0.],[0., 0., 0.]]
    # horizontal kernel
    Kh = [[0., 0., 0.],[-1., 1., 0.], [0., 0., 0.]]
    # filtering
    for y in range(H):
        for x in range(W):
            out_v[pad + y, pad + x] = np.sum(Kv * (tmp[y: y + K_size, x: x + K_size]))
            out_h[pad + y, pad + x] = np.sum(Kh * (tmp[y: y + K_size, x: x + K_size]))
    out_v = np.clip(out_v, 0, 255)
    out_h = np.clip(out_h, 0, 255)
    out_v = out_v[pad: pad + H, pad: pad + W].astype(np.uint8)
    out_h = out_h[pad: pad + H, pad: pad + W].astype(np.uint8)
    return out_v, out_h

Sobel滤波器

def sobel_filter(img, K_size=3):
    if len(img.shape) == 3:
        H, W, C = img.shape
    else:
        img = np.expand_dims(img, axis=-1)
        H, W, C = img.shape
    # Zero padding
    pad = K_size // 2   注意啊,前面的灰色//2可不是注释,这是python3的真除法的写法,意思是取商
    out = np.zeros((H + pad * 2, W + pad * 2), dtype=np.float)
    out[pad: pad + H, pad: pad + W] = gray.copy().astype(np.float)
    tmp = out.copy()
    out_v = out.copy()
    out_h = out.copy()
    ## Sobel vertical
    Kv = [[1., 2., 1.],[0., 0., 0.], [-1., -2., -1.]]
    ## Sobel horizontal
    Kh = [[1., 0., -1.],[2., 0., -2.],[1., 0., -1.]]
    # filtering
    for y in range(H):
        for x in range(W):
            out_v[pad + y, pad + x] = np.sum(Kv * (tmp[y: y + K_size, x: x + K_size]))
            out_h[pad + y, pad + x] = np.sum(Kh * (tmp[y: y + K_size, x: x + K_size]))
    out_v = np.clip(out_v, 0, 255)
    out_h = np.clip(out_h, 0, 255)
    out_v = out_v[pad: pad + H, pad: pad + W].astype(np.uint8)
    out_h = out_h[pad: pad + H, pad: pad + W].astype(np.uint8)
    return out_v, out_h

Prewitt滤波器

def prewitt_filter(img, K_size=3):
    if len(img.shape) == 3:
        H, W, C = img.shape
    else:
        img = np.expand_dims(img, axis=-1)
        H, W, C = img.shape
    # Zero padding
    pad = K_size // 2    注意啊,前面的灰色//2可不是注释,这是python3的真除法的写法,意思是取商
    out = np.zeros((H + pad * 2, W + pad * 2), dtype=np.float)
    out[pad: pad + H, pad: pad + W] = gray.copy().astype(np.float)
    tmp = out.copy()
    out_v = out.copy()
    out_h = out.copy()
    ## prewitt vertical kernel
    Kv = [[-1., -1., -1.],[0., 0., 0.], [1., 1., 1.]]
    ## prewitt horizontal kernel
    Kh = [[-1., 0., 1.],[-1., 0., 1.],[-1., 0., 1.]]
    # filtering
    for y in range(H):
        for x in range(W):
            out_v[pad + y, pad + x] = np.sum(Kv * (tmp[y: y + K_size, x: x + K_size]))
            out_h[pad + y, pad + x] = np.sum(Kh * (tmp[y: y + K_size, x: x + K_size]))
    out_v = np.clip(out_v, 0, 255)
    out_h = np.clip(out_h, 0, 255)
    out_v = out_v[pad: pad + H, pad: pad + W].astype(np.uint8)
    out_h = out_h[pad: pad + H, pad: pad + W].astype(np.uint8)
    return out_v, out_h

Laplacian滤波器

def laplacian_filter(img, K_size=3):
    H, W, C = img.shape
    # zero padding
    pad = K_size // 2    注意啊,前面的灰色//2可不是注释,这是python3的真除法的写法,意思是取商
    out = np.zeros((H + pad * 2, W + pad * 2), dtype=np.float)
    out[pad: pad + H, pad: pad + W] = gray.copy().astype(np.float)
    tmp = out.copy()
    # laplacian kernle
    K = [[0., 1., 0.],[1., -4., 1.], [0., 1., 0.]]
    # filtering
    for y in range(H):
        for x in range(W):
            out[pad + y, pad + x] = np.sum(K * (tmp[y: y + K_size, x: x + K_size]))
    out = np.clip(out, 0, 255)
    out = out[pad: pad + H, pad: pad + W].astype(np.uint8)
    return out

Emboss滤波器

def emboss_filter(img, K_size=3):
    H, W, C = img.shape
    # zero padding
    pad = K_size // 2   注意啊,前面的灰色//2可不是注释,这是python3的真除法的写法,意思是取商
    out = np.zeros((H + pad * 2, W + pad * 2), dtype=np.float)
    out[pad: pad + H, pad: pad + W] = gray.copy().astype(np.float)
    tmp = out.copy()
    # emboss kernel
    K = [[-2., -1., 0.],[-1., 1., 1.], [0., 1., 2.]]
    # filtering
    for y in range(H):
        for x in range(W):
            out[pad + y, pad + x] = np.sum(K * (tmp[y: y + K_size, x: x + K_size]))
    out = np.clip(out, 0, 255)
    out = out[pad: pad + H, pad: pad + W].astype(np.uint8)
    return out

LoG滤波器

//log滤波器公式与高斯滤波器公式较为相似,为高斯滤波器和拉普拉斯滤波器的组合,具体见代码公式
def LoG_filter(img, K_size=5, sigma=3):
    H, W, C = img.shape
    # zero padding
    pad = K_size // 2     注意啊,前面的灰色//2可不是注释,这是python3的真除法的写法,意思是取商
    out = np.zeros((H + pad * 2, W + pad * 2), dtype=np.float)
    out[pad: pad + H, pad: pad + W] = gray.copy().astype(np.float)
    tmp = out.copy()
    # LoG Kernel
    K = np.zeros((K_size, K_size), dtype=np.float)
    for x in range(-pad, -pad + K_size):
        for y in range(-pad, -pad + K_size):
            K[y + pad, x + pad] = (x ** 2 + y ** 2 - sigma ** 2) * np.exp( -(x ** 2 + y ** 2) / (2 * (sigma ** 2)))
    K /= (2 * np.pi * (sigma ** 6))
    K /= K.sum()
    # filtering
    for y in range(H):
        for x in range(W):
            out[pad + y, pad + x] = np.sum(K * tmp[y: y + K_size, x: x + K_size])
    out = np.clip(out, 0, 255)
    out = out[pad: pad + H, pad: pad + W].astype(np.uint8)
    return out
上一篇 下一篇

猜你喜欢

热点阅读