图像增强-基于滤波的方法

图像增强-基于滤波的方法

小记一下多种滤波方法的代码实现!

  • 局部二值模式(LBP)

    1996年由Ojala提出的特征提取方法,具有灰度不变性和旋转不变性,主要用于纹理特征提取。其基本思想是:用中心像素的灰度值作为阈值,与它的邻域相比较得到的二进制码来表述局部纹理特征。

    以中心点为基准,在3*3的窗口内,与8个相邻点进行比较,若小于中心点,则该位置被置0,否则被置1,这样可以得到一个8位二进制数,即共256种的LBP码。然后利用这个LBP值来反映该区域的纹理信息,值得注意的是,LBP值是顺时针组成的二进制数。

    import cv2
    import numpy as np
    import matplotlib.pyplot as plt
    import matplotlib.image as mpimg
    %matplotlib inline
    
    #释放窗口
    def releaseWin():
        cv2.waitKey(0)
        cv2.destroyAllWindows()
        key = cv2.waitKey(0)
        if key==27:
            print(key)
            c2v.destroyAllWindows()
    
    def origin_LBP(img):
        dst = np.zeros(img.shape,dtype=img.dtype)
        h,w=img.shape
        for i in range(1,h-1):
            for j in range(1,w-1):
                center = img[i][j]
                code = 0
                 
                code |= (img[i-1][j-1] >= center) << (np.uint8)(7)  
                code |= (img[i-1][j  ] >= center) << (np.uint8)(6)  
                code |= (img[i-1][j+1] >= center) << (np.uint8)(5)  
                code |= (img[i  ][j+1] >= center) << (np.uint8)(4)  
                code |= (img[i+1][j+1] >= center) << (np.uint8)(3)  
                code |= (img[i+1][j  ] >= center) << (np.uint8)(2)  
                code |= (img[i+1][j-1] >= center) << (np.uint8)(1)  
                code |= (img[i  ][j-1] >= center) << (np.uint8)(0)  
      
                dst[i-1][j-1]= code
        return dst
    
    gray = cv2.imread(r'C:\Users\admin\Desktop\Data\ComputerVision\exp1\testPic\peppers.png', cv2.IMREAD_GRAYSCALE)
    # cv2.imshow('img', gray)
    org_lbp = origin_LBP(gray)
    # cv2.imshow('org_lbp', org_lbp)
    plt.imshow(gray, cmap='gray')
    plt.show()
    plt.imshow(org_lbp, cmap='gray')
    plt.show()
    # releaseWin()
    
  • 均值滤波

    均值滤波器是包含在滤波器邻域内像素的平均值,其作用是减小图像灰度的“尖锐”变化,减小噪声,但也会存在边缘模糊的问题。

    def mean_filter(x, y, step):
        sum_s = 0
        for k in range(-int(step/2),int(step/2)+1):
            for m in range(-int(step/2),int(step/2)+1):
                sum_s += img[x+k][y+m] / (step*step)
        return sum_s
    
    img = cv2.imread(r'C:\Users\admin\Desktop\Data\ComputerVision\exp1\testPic\save2.bmp',0)
    mean_img = img.copy()
    medStep = 3
    for i in range(int(medStep/2),img.shape[0]-int(medStep/2)):
        for j in range(int(medStep/2),img.shape[1]-int(medStep/2)):
            mean_img[i][j] = mean_filter(i, j, medStep)
    plt.imshow(img, cmap='gray')
    plt.show()
    plt.imshow(mean_img, cmap='gray')
    plt.show()
    
  • 非线性滤波

    非线性滤波器包括了中值滤波器、最大值滤波器和最小值滤波器,分别是用像素领域内的中间值、最大值、最小值代替像素,作用分别是去除噪声、寻找最亮点、寻找最暗点。

    Ø 中值滤波

    用像素领域内的中间值代替像素

    def m_filter(x, y, step):
        sum_s=[]
        for k in range(-int(step/2),int(step/2)+1):
            for m in range(-int(step/2),int(step/2)+1):
                sum_s.append(img[x+k][y+m])
        sum_s.sort()
        return sum_s[(int(step*step/2)+1)]
    
    img = cv2.imread(r'C:\Users\admin\Desktop\Data\ComputerVision\exp1\testPic\save2.bmp',0)
    mid_img = img.copy()
    medStep = 3
    for i in range(int(medStep/2),img.shape[0]-int(medStep/2)):
        for j in range(int(medStep/2),img.shape[1]-int(medStep/2)):
            mid_img[i][j] = m_filter(i, j, medStep)
    plt.imshow(img, cmap='gray')
    plt.show()
    plt.imshow(mid_img, cmap='gray')
    plt.show()
    

    Ø 最大值滤波

    用像素领域内的最大值代替像素

    def max_filter(x, y, step):
        sum_s=[]
        for k in range(-int(step/2),int(step/2)+1):
            for m in range(-int(step/2),int(step/2)+1):
                sum_s.append(img[x+k][y+m])
        return max(sum_s)
    
    def min_filter(x, y, step):
        sum_s=[]
        for k in range(-int(step/2),int(step/2)+1):
            for m in range(-int(step/2),int(step/2)+1):
                sum_s.append(img[x+k][y+m])
        return min(sum_s)
    
    img = cv2.imread(r'C:\Users\admin\Desktop\Data\ComputerVision\exp1\testPic\save2.bmp',0)
    mid_img = img.copy()
    medStep = 3
    for i in range(int(medStep/2),img.shape[0]-int(medStep/2)):
        for j in range(int(medStep/2),img.shape[1]-int(medStep/2)):
            mid_img[i][j] = max_filter(i, j, medStep)
    plt.imshow(img, cmap='gray')
    plt.show()
    plt.imshow(mid_img, cmap='gray')
    plt.show()
    

    Ø 最小值滤波

    用像素领域内的最小值代替像素

    def min_filter(x, y, step):
        sum_s=[]
        for k in range(-int(step/2),int(step/2)+1):
            for m in range(-int(step/2),int(step/2)+1):
                sum_s.append(img[x+k][y+m])
        return min(sum_s)
    
    img = cv2.imread(r'C:\Users\admin\Desktop\Data\ComputerVision\exp1\testPic\save2.bmp',0)
    mid_img = img.copy()
    medStep = 3
    for i in range(int(medStep/2),img.shape[0]-int(medStep/2)):
        for j in range(int(medStep/2),img.shape[1]-int(medStep/2)):
            mid_img[i][j] = min_filter(i, j, medStep)
    plt.imshow(img, cmap='gray')
    plt.show()
    plt.imshow(mid_img, cmap='gray')
    plt.show()
    
  • 高斯滤波

    高斯滤波是一种线性平滑滤波器,对于服从正态分布的噪声有很好的抑制效果,通常我们都会假定白噪声为高斯噪声,实际应用中常用高斯滤波来抑制噪声。

    例如标准差为1.3的3*3大小的整数形式的高斯滤波器,不难发现,最重要的参数是高斯分布的标准差σ,当σ越小,生成的算子中心系数较大,平滑的效果不会很明显;当σ越大,生成的算子各个系数相差较小,平滑效果会更加明显。

    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
     
        ## Zero padding
        pad = K_size // 2
        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)
     
        ## 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 = np.clip(out, 0, 255)
        out = out[pad: pad + H, pad: pad + W].astype(np.uint8)
        return out
    
    img = cv2.imread(r'C:\Users\admin\Desktop\Data\ComputerVision\exp1\testPic\rice_gaussian_0_0.01.bmp',0)
    res_img = gaussian_filter(img, K_size=3, sigma=0.6)
    res_img2 = gaussian_filter(img, K_size=3, sigma=1.3)
    plt.imshow(img, cmap='gray')
    plt.show()
    plt.imshow(res_img, cmap='gray')
    plt.show()
    plt.imshow(res_img2, cmap='gray')
    plt.show()
    
  • 图像锐化

    与前几个滤波作用(平滑)相反的是,我们可以对图像进行锐化操作,突出图像的边缘。具体实现方法包括了一阶导数和二阶导数,分别利用Sobel算子和Laplacian算子进行滤波。

    Ø Sobel算子

    Sobel算子包括横向和纵向两种算子如下所示,分别提取竖直边缘和水平边缘。

    def SobelOperator(roi, operator_type):
        if operator_type == "horizontal":
            sobel_operator = np.array([[-1, -2, -1], [0, 0, 0], [1, 2, 1]]) #横向模板
        elif operator_type == "vertical":
            sobel_operator = np.array([[-1, 0, 1], [-2, 0, 2], [-1, 0, 1]]) #纵向模板
        else:
            raise ("type Error")
        result = np.abs(np.sum(roi * sobel_operator))
        return result
    
    def SobelAlogrithm(image):
        new_image1 = np.zeros(image.shape)
        new_image2 = np.zeros(image.shape)
        for i in range(1, image.shape[0] - 1):
            for j in range(1, image.shape[1] - 1):
                new_image1[i - 1, j - 1] = SobelOperator(image[i - 1:i + 2, j - 1:j + 2], 'horizontal')
                new_image2[i - 1, j - 1] = SobelOperator(image[i - 1:i + 2, j - 1:j + 2], 'vertical')
        new_image1 = np.sqrt(new_image1*new_image1+new_image2*new_image2)
        new_image1 = 255 - new_image1*(255 / np.max(new_image1))
        return new_image1.astype(np.uint8)
    
    img = cv2.imread(r'C:\Users\admin\Desktop\Data\ComputerVision\exp1\testPic\mytable.jpg',0)
    img = cv2.resize(img,(img.shape[1]//5,img.shape[0]//5))
    plt.imshow(img, cmap='gray')
    plt.show()
    plt.imshow(SobelAlogrithm(img), cmap='gray')
    plt.show()
    plt.imshow(SobelAlogrithm(img), cmap='binary')
    

    Ø Laplacian算子

    Laplacian算子的操作过程域Sobel算子基本一致,它具有4邻域算子和8邻域算子。

    def LaplaceOperator(roi, operator_type):
        if operator_type == "fourfields":
            laplace_operator = np.array([[0, 1, 0], [1, -4, 1], [0, 1, 0]])
        elif operator_type == "eightfields":
            laplace_operator = np.array([[1, 1, 1], [1, -8, 1], [1, 1, 1]])
        else:
            raise ("type Error")
        result = np.abs(np.sum(roi * laplace_operator))
        return result
    
    def LaplaceAlogrithm(image, operator_type):
        new_image = np.zeros(image.shape)
        image = cv2.copyMakeBorder(image, 1, 1, 1, 1, cv2.BORDER_DEFAULT)
        for i in range(1, image.shape[0] - 1):
            for j in range(1, image.shape[1] - 1):
                new_image[i - 1, j - 1] = LaplaceOperator(image[i - 1:i + 2, j - 1:j + 2], operator_type)
        new_image = 255-new_image * (255 / np.max(image))
        return new_image.astype(np.uint8)
    
    img = cv2.imread(r'C:\Users\admin\Desktop\Data\ComputerVision\exp1\testPic\mytable.jpg',0)
    img = cv2.resize(img,(img.shape[1]//5,img.shape[0]//5))
    plt.imshow(img, cmap='gray')
    plt.show()
    plt.imshow(LaplaceAlogrithm(img,'fourfields'), cmap='gray')
    plt.show()
    plt.imshow(LaplaceAlogrithm(img,'fourfields'), cmap='binary')
    
  • Gabor滤波

    Gabor滤波也是用来提取图像边缘的方法.

    import cv2
    import numpy as np
    import matplotlib.pyplot as plt
    
    # Grayscale
    def BGR2GRAY(img):
        # Grayscale
        gray = 0.2126 * img[..., 2] + 0.7152 * img[..., 1] + 0.0722 * img[..., 0]
        return gray
    
    # Gabor Filter
    def Gabor_filter(K_size=111, Sigma=10, Gamma=1.2, Lambda=10, Psi=0, angle=0):
        # get half size
        d = K_size // 2
        # prepare kernel
        gabor = np.zeros((K_size, K_size), dtype=np.float32)
        # each value
        for y in range(K_size):
            for x in range(K_size):
                # distance from center
                px = x - d
                py = y - d
                # degree -> radian
                theta = angle / 180. * np.pi
                # get kernel x
                _x = np.cos(theta) * px + np.sin(theta) * py
                # get kernel y
                _y = -np.sin(theta) * px + np.cos(theta) * py
                # fill kernel
                gabor[y, x] = np.exp(-(_x**2 + Gamma**2 * _y**2) / (2 * Sigma**2)) * np.cos(2*np.pi*_x/Lambda + Psi)
        # kernel normalization
        gabor /= np.sum(np.abs(gabor))
    
        return gabor
    
    
    # 使用Gabor滤波器作用于图像上
    def Gabor_filtering(gray, K_size=111, Sigma=10, Gamma=1.2, Lambda=10, Psi=0, angle=0):
        # get shape
        H, W = gray.shape
        # padding
        gray = np.pad(gray, (K_size//2, K_size//2), 'edge')
        # prepare out image
        out = np.zeros((H, W), dtype=np.float32)
        # get gabor filter
        gabor = Gabor_filter(K_size=K_size, Sigma=Sigma, Gamma=Gamma, Lambda=Lambda, Psi=0, angle=angle)
        # filtering
        for y in range(H):
            for x in range(W):
                out[y, x] = np.sum(gray[y : y + K_size, x : x + K_size] * gabor)
    
        out = np.clip(out, 0, 255)
        out = out.astype(np.uint8)
    
        return out
    
    
    # 使用6个不同角度的Gabor滤波器对图像进行特征提取
    def Gabor_process(img):
        # get shape
        H, W = img.shape
        # gray scale
    #     gray = BGR2GRAY(img).astype(np.float32)
        # define angle
        #As = [0, 45, 90, 135]
        As = [0,30,60,90,120,150]
        # prepare pyplot
        plt.subplots_adjust(left=0, right=1, top=1, bottom=0, hspace=0, wspace=0.2)
        out = np.zeros([H, W], dtype=np.float32)
    
        # each angle
        for i, A in enumerate(As):
            # gabor filtering
            _out = Gabor_filtering(img, K_size=11, Sigma=1.5, Gamma=1.2, Lambda=3, angle=A)
            # add gabor filtered image
            out += _out
        # scale normalization
        out = out / out.max() * 255
        out = out.astype(np.uint8)
        return out
    
    # Read image
    img = cv2.imread(r'C:\Users\admin\Desktop\Data\ComputerVision\exp1\testPic\mytable.jpg',0)
    img = cv2.resize(img,(img.shape[1]//5,img.shape[0]//5)).astype(np.float32)
    # img = cv2.imread(r'C:\Users\admin\Desktop\Data\ComputerVision\exp1\testPic\mytable.jpg').astype(np.float32)
    # gabor process
    out = Gabor_process(img)
    plt.imshow(img, cmap='gray')
    plt.show()
    plt.imshow(out, cmap='gray')
    plt.show()
    plt.imshow(out, cmap='binary')
    
  • 3
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

路过的风666

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值