Skip to content

Week 12 Assignment

题目要求:

  1. 使用平滑函数 \(h(x)=\exp(\sqrt{x^2+y^2}/120)\) (尺寸7×7)与 DIP 图卷积产生模糊,然后用逆滤波实现对有模糊图像的恢复。
  2. 在模糊图像上叠加高斯噪声(均值0,方差8、16、24),对比逆滤波与维纳滤波对图像的恢复效果。
  3. 在原始图像上再叠加其他退化因素(如运动模糊、湍流或其他噪声等)后再次进行实验,给出退化图像及恢复后的图像。
  4. 使用其他方法对图像进行恢复,对比效果。
  5. 最后显示结果注意归一化。

Prepare modules

文件 noise.py ,包含生成指数模糊卷积核、运动模糊卷积核、模糊图像、为图像添加高斯噪声等。

Python
import cv2
import numpy as np


def exp_kernel(size=7, D0=120):
    assert size % 2 == 1, "Kernel size must be odd."
    center = size // 2
    kernel = np.zeros((size, size), dtype=np.float32)

    for i in range(size):
        for j in range(size):
            x = i - center
            y = j - center
            kernel[i, j] = np.exp(np.sqrt(x**2 + y**2) / D0)

    kernel /= np.sum(kernel)
    return kernel


def motion_kernel(size=7, angle=0):
    assert size % 2 == 1, "Kernel size must be odd."
    psf = np.zeros((size, size), dtype=np.float32)
    psf[(size - 1) // 2, :] = 1.0
    M = cv2.getRotationMatrix2D((size / 2 - 0.5, size / 2 - 0.5), angle, 1)
    psf = cv2.warpAffine(psf, M, (size, size))
    psf /= psf.sum()
    return psf


def blur_image(image, kernel):
    output = cv2.filter2D(image, ddepth=-1, kernel=kernel)
    return output


def add_gaussian_noise(image, mean=0, var=25):
    sigma = np.sqrt(var)
    noise = np.random.normal(mean, sigma, image.shape).astype(np.float32)

    output = image.astype(np.float32) + noise
    output = np.clip(output, 0, 255).astype(np.uint8)
    return output

文件 restore.py ,包含逆滤波、维纳滤波、最小平方法等图像复原的函数。

Python
import numpy as np


def inverse_filter(image, H_degrade, k=0.5, d=0.1, eps=1e-3):
    G = np.fft.fft2(image.astype(np.float32))
    M = np.where(np.abs(H_degrade) <= d, k, 1.0 / (H_degrade + eps))

    F_hat = G * M
    f_hat = np.fft.ifft2(F_hat)
    f_hat = np.real(f_hat).clip(0, 255).astype(np.uint8)
    return f_hat


def wiener_filter(image, H_degrade, K=0.01):
    G = np.fft.fft2(image.astype(np.float32))
    M = np.conj(H_degrade) / (np.abs(H_degrade) ** 2 + K)

    F_hat = G * M
    f_hat = np.fft.ifft2(F_hat)
    f_hat = np.real(f_hat).clip(0, 255).astype(np.uint8)
    return f_hat


def cls_filter(image, H_degrade, s=0.01):
    G = np.fft.fft2(image.astype(np.float32))

    # fmt: off
    lap = np.array([
        [0, -1, 0],
        [-1, 4, -1],
        [0, -1, 0]
    ], dtype=np.float32)
    # fmt: on
    P = np.fft.fft2(np.fft.ifftshift(lap), s=image.shape)

    M = np.conj(H_degrade) / (np.abs(H_degrade) ** 2 + s * np.abs(P) ** 2)

    F_hat = G * M
    f_hat = np.fft.ifft2(F_hat)
    f_hat = np.real(f_hat).clip(0, 255).astype(np.uint8)
    return f_hat

Task 1

先使用指数平滑函数 \(h(x,y)=\exp(\sqrt{x^2+y^2}/120)\) 卷积产生模糊,然后使用逆滤波进行图像恢复,逆滤波函数采用:

$$ M(u,v)=\begin{cases}\ k, & H(u,v)

Comments