4.2 Python图像的图像恢复-组合滤波器

4.2 Python图像的图像恢复-组合滤波器

1 算法原理

1.1 混合滤波器

本文以中值滤波+巴特沃斯低通滤波+同态滤波混合滤波器为例,读者可以自由组合其他滤波器。

本混合滤波器算法设计思路:先对图片添加椒盐噪声,先采用中值滤波器进行去噪处理,然后采用巴特沃斯低通滤波和同态滤波混合滤波器进行图像处理。巴特沃斯低通滤波器和同态滤波器在上一节已经介绍过其原理,这里不再重复给出。

中值滤波–cv2.medianBlur(src, ksize)。这里的核大小 ksize 必须是奇数,将该点周围的像素点包括本身,按次序排列,取中位数作为点的像素值。中值滤波器的特点为:随着核大小逐渐变大,会让图像变得更加模糊;核必须是大于 1 的奇数,如 3、5、7 等;在代码 dst = cv2.medianBlur(src, ksize) 中 填写核大小时,只需填写一个数即可,如 3、5、7 ,9等,对比均值滤波函数用法。

1.2 选择性滤波器

选择性滤波主要有两类:

带阻滤波器或带通滤波器; 陷波滤波器。陷波滤波器是更有用的选择性滤波器可以有效的去除周期性噪声。陷波滤波器可以用高通滤波器的乘积来构造。一般形式为:

image-20210716151122422

其中,Hk(u,v)和 H−k(u,v)是高通滤波器。距离的计算:

image-20210716151251502

和:

image-20210716151314307

本次实验采用陷波滤波器作为选择性滤波器的算法实现,它包含两个陷波对:

image-20210716151324593

2 代码

运行代码说明

1.要改变代码中的图片地址(地址不能有中文)

更改put(path)函数中的路径put(r'../image/image1.jpg')

2.注意最后的plt.savefig('1.new.jpg')是保存plt图像,如果不使用可以注释掉

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# author:mgboy time:2021/6/26

import os
import numpy as np
import cv2
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False

# 巴特沃斯低通滤波器
def ButterworthLowPassFilter(image, d, n, s1):
    """
    Butterworth低通滤波器
    """
    f = np.fft.fft2(image)
    fshift = np.fft.fftshift(f)

    def make_transform_matrix(d):
        transform_matrix = np.zeros(image.shape)
        center_point = tuple(map(lambda x: (x - 1) / 2, s1.shape))
        for i in range(transform_matrix.shape[0]):
            for j in range(transform_matrix.shape[1]):

                def cal_distance(pa, pb):
                    from math import sqrt

                    dis = sqrt((pa[0] - pb[0]) ** 2 + (pa[1] - pb[1]) ** 2)
                    return dis
                dis = cal_distance(center_point, (i, j))
                transform_matrix[i, j] = 1 / (1 + (dis / d) ** (2 * n))
        return transform_matrix


    d_matrix = make_transform_matrix(d)
    new_img = np.abs(np.fft.ifft2(np.fft.ifftshift(fshift * d_matrix)))
    return new_img

# 同态滤波器
def homomorphic_filter(src, d0=10, r1=0.5, rh=2, c=4, h=2.0, l=0.5):
    gray = src.copy()
    if len(src.shape) > 2:
        gray = cv2.cvtColor(src, cv2.COLOR_BGR2GRAY)
    gray = np.float64(gray)
    rows, cols = gray.shape

    gray_fft = np.fft.fft2(gray)
    gray_fftshift = np.fft.fftshift(gray_fft)
    dst_fftshift = np.zeros_like(gray_fftshift)
    M, N = np.meshgrid(np.arange(-cols // 2, cols // 2), np.arange(-rows // 2, rows // 2))
    D = np.sqrt(M ** 2 + N ** 2)
    Z = (rh - r1) * (1 - np.exp(-c * (D ** 2 / d0 ** 2))) + r1
    dst_fftshift = Z * gray_fftshift
    dst_fftshift = (h - l) * dst_fftshift + l
    dst_ifftshift = np.fft.ifftshift(dst_fftshift)
    dst_ifft = np.fft.ifft2(dst_ifftshift)
    dst = np.real(dst_ifft)
    dst = np.uint8(np.clip(dst, 0, 255))
    return dst

def salt_pepper(image, salt, pepper):
    """
    添加椒盐噪声的图像
    :param image: 输入图像
    :param salt: 盐比例
    :param pepper: 椒比例
    :return: 添加了椒盐噪声的图像
    """
    height = image.shape[0]
    width = image.shape[1]
    pertotal = salt + pepper    #总噪声占比
    noise_image = image.copy()
    noise_num = int(pertotal * height * width)
    for i in range(noise_num):
        rows = np.random.randint(0, height-1)
        cols = np.random.randint(0,width-1)
        if(np.random.randint(0,100)<salt*100):
            noise_image[rows][cols] = 255
        else:
            noise_image[rows][cols] = 0
    return noise_image

def put(path):
    img = cv2.imread(path, 1)
    # img = cv2.imread(os.path.join(base, path), 1)
    img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    # 傅里叶变换
    f = np.fft.fft2(img)
    fshift = np.fft.fftshift(f)
    # 取绝对值后将复数变化为实数,取对数的目的是将数据变换到0~255
    s1 = np.log(np.abs(fshift))
    # 加入椒盐噪声
    noise = salt_pepper(img, 0.05, 0.05)
    # 经过中值滤波器消除噪声
    res = cv2.medianBlur(noise, 5)
    # 图像经过巴特沃斯低通滤波器处理
    # 设置D=100,N=1
    res = ButterworthLowPassFilter(res, 100, 1,s1)
    # 处理过的图像再经过同态滤波处理
    res = homomorphic_filter(res, 100, 1)

    res = ButterworthLowPassFilter(res, 100, 1,s1)

    f = np.fft.fft2(noise)
    fshift = np.fft.fftshift(f)
    w, h = img.shape
    """设计理想陷波滤波器"""
    flt = np.zeros(noise.shape)
    rx1 = w / 4
    ry1 = h / 2
    rx2 = w * 3 / 4
    ry2 = h / 2;
    r = min(w, h) / 6  # 半径
    for i in range(1, w):
        for j in range(1, h):
            if ((i - rx1) ** 2 + (j - ry1) ** 2 >= r ** 2) and ((i - rx2) ** 2 + (j - ry2) ** 2 >= r ** 2):
                flt[i, j] = 1
    # 选择滤波
    new_img = np.abs(np.fft.ifft2(np.fft.ifftshift(fshift * flt)))

    plt.subplot(231)
    plt.axis('off')
    plt.title('原始图像')
    plt.imshow(img, cmap='gray')
    plt.subplot(232)
    plt.axis('off')
    plt.title('噪声图像')
    plt.imshow(noise, cmap='gray')
    plt.subplot(233)
    plt.axis('off')
    plt.title('混合滤波器')
    plt.imshow(res, cmap='gray')
    plt.subplot(234),plt.axis('off'),plt.imshow(s1,'gray'),plt.title('中心频率域')
    plt.subplot(235), plt.axis('off'), plt.imshow(flt, 'gray'), plt.title('陷波滤波器')
    plt.subplot(236),plt.axis('off'),plt.imshow(new_img,'gray'),plt.title('选择性滤波器')

    # plt.savefig('2.new.jpg')
    plt.show()


# 图像处理函数,要传入路径
put(r'../image/image3.jpg')

3 效果

image-20210723105118366
在这里插入图片描述

image-20210723105137283

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值