数字图像处理-灰度图像的高斯滤波

问题描述

将彩色图像转换为NTSC的灰度图像进行高斯滤波,采用σ=1,2,3,5。任
选一种像素填补方案。对于σ=1 下的结果,与直接调用相关函数的结果进行比较(可以简单计算差值图像)。然后,任选两幅图像,比较其他参数条件不变的情况下像素复制和补零下滤波结果在边界上的差别。

代码实现

导库

import  numpy as np
import warnings
import cv2

灰度转换函数

def  rgb1gray(f, method='NTSC'):
    if method == 'average':
        g = (f[:,:,0]+f[:,:,1]+f[:,:,2]) / 3
        g = g.clip(0, 1)
        return g

    elif method == 'NTSC':
        g = 0.2989*f[:, :, 0] + 0.5870*f[:, :, 1] + 0.1140*f[:, :, 2]
        g = g.clip(0, 1)
        return g
    else:
        raise Exception("输入格式有误")

高斯滤波核生成函数
高斯滤波核函数 w = gaussKernel(sig,m),其中 sig 对应于高斯函数定义中的σ,w的大小为 m×m。请注意,这里如果 m 没有提供,需要进行计算确定。如果 m 已提供但过小,应给出警告信息提示。w 要求归一化,即全部元素加起来和为 1。

def  gaussKernel(sig=None,m=0):
    #抛出异常
    if sig==None:
        raise Exception("输入格式有误")
    else:
        if m == 0:
        #m未给出,自己计算
            m = int(sig * 2 * 3 + 1)
            print('计算的m',m)
        elif m< sig*1*3+1:
        #警告提示
            warnings.warn('m太小')
        w = np.zeros((m, m), dtype=np.float)
        middle_m = m//2
        #生成高斯核
        for x in range(-middle_m, - middle_m + m):
            for y in range(-middle_m, - middle_m + m):
                w[y + middle_m, x + middle_m] = np.exp(-(x ** 2 + y ** 2) / (2 * (sig ** 2)))
        w /= (sig * np.sqrt(2 * np.pi))
        #归一化
        w /= w.sum()
        return w

归一化函数

#归一化
def normalization(data):
    _range = np.max(data) - np.min(data)
    return (data - np.min(data)) / _range

高斯滤波函数

#滤波
def twodConv(f, w, method='zero'):
    x, y = w.shape
    fh, fw = f.shape
    nh = fh + x - 1
    nw = fw + y - 1
    add_h = int(x) // 2
    add_w = int(y) // 2
    n = np.zeros((nh, nw))
    g = np.zeros((fh, fw))
    n[add_h:nh - add_h, add_w:nw - add_w] = f
    if method == 'replicate':
        n[0:add_h,add_w:nw-add_w] = f[0,:]
        n[nh-add_h:,add_w:nw-add_w] = f[-1,:]
        for i in range(add_w):
            n[:,i] = n[:,add_w]
            n[:,nw-1-i] = n[:,nw-1-add_w]
        for i in range(fh):
            for j in range(fw):
                g[i,j] = np.sum(n[i:i+x,j:j+y] * w)
        g = g.clip(0,1)
        return g
    if method == 'zero':
        for i in range(fh):
            for j in range(fw):
                g[i,j] = np.sum(n[i:i+x,j:j+y] * w)
        g = g.clip(0,1)
        return g

主函数

if __name__ == '__main__':
    sig = [1, 2, 3, 5]
    # 图片导入
    f1= cv2.imread("cameraman.tif",cv2.IMREAD_GRAYSCALE)
    f2 = cv2.imread("einstein.tif",cv2.IMREAD_GRAYSCALE)
    f3 = cv2.imread("mandril_color.tif")
    f4 = cv2.imread("lena512color.tiff")
    #彩色图转灰度图
    f3 = rgb1gray.rgb1gray(normalization(f3))
    f4 = rgb1gray.rgb1gray(normalization(f4))

    for i in sig:
        w = gaussKernel.gaussKernel(i)
        g1 = twodConv(normalization(f1), w, method='replicate')
        g2 = twodConv(normalization(f2), w, method='replicate')
        g3 = twodConv(f3, w, method='replicate')
        g4 = twodConv(f4, w, method='replicate')
        cv2.imshow('sig='+str(i)+',cameraman', g1)
        cv2.imshow('sig='+str(i)+',einstein', g2)
        cv2.imshow('sig='+str(i)+',mandril_gray', g3)
        cv2.imshow('sig='+str(i)+',lena512gray', g4)


    #sig==1时,,与直接调用相关函数的结果进行比较
    w = gaussKernel.gaussKernel(1)
    g11 = twodConv(normalization(f1), w, method='replicate')
    g12 = twodConv(normalization(f2), w, method='replicate')
    g13 = twodConv(f3, w, method='replicate')
    g14 = twodConv(f4, w, method='replicate')
    F = [f1,f2,f3,f4]
    G = [g11,g12,g13,g14]
    OG = []
    C = []
    #opencv 方法
    for i in F:
        og = cv2.GaussianBlur(i,(7,7),1,borderType=cv2.BORDER_REPLICATE)
        og =  normalization(og)
        OG.append(og)
    OG = np.array(OG)
    G = np.array(G)
    C = np.abs(OG-G)
    for i in range(4):
        cv2.imshow(str(i)+',OpenCV', OG[i])
        cv2.imshow( str(i) + ',diff', C[i])


    #对比像素复制和补零下滤波结果在边界上的差别
    for i in sig:
        w = gaussKernel.gaussKernel(i)
        g1 = twodConv(normalization(f1), w, method='replicate')
        g2 = twodConv(normalization(f2), w, method='replicate')
        g3 = twodConv(normalization(f1), w)
        g4 = twodConv(normalization(f2), w)
        # cv2.imshow('sig='+str(i)+',cameraman_r', g1)
        # cv2.imshow('sig='+str(i)+',einstein_r', g2)
        cv2.imshow('sig='+str(i)+',cameraman_z', g3)
        cv2.imshow('sig='+str(i)+',einstein_z', g4)
        cv2.imshow('sig=' + str(i) + ',cameraman_diff', np.abs(g3-g1))
        cv2.imshow('sig=' + str(i) + ',einstein_diff', np.abs(g4-g2))
    cv2.waitKey(0)
    cv2.destroyAllWindows()

结果展示

在这里插入图片描述
在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值