图像去噪–总变差去噪(TV)

引用资料:
1.全变分图像去噪算法(TV)
2.TV去噪的理解

总变差去噪 (Total Variation Denoising) 是一种经典的图像去噪方法,能够有效减少噪声,同时保留图像的边缘细节。该方法的核心思想是通过最小化图像的“总变差”来实现图像平滑,避免过度平滑损失边缘。

下图来自:1.全变分图像去噪算法(TV)

下图来自:1.全变分图像去噪算法(TV)

1.1 定义全变分

1.1.1 数学定义

全变分(TV)度量图像中梯度变化的总量,它是衡量图像平滑程度的一个关键指标。在图像去噪中,全变分的定义帮助我们描述图像的整体变化,尤其是边缘区域的变化。

1.1.2 疑问一:为什么要对图像梯度求绝对值?

1.1.3 疑问二:为什么要对图像梯度的绝对值进行积分?

1.2 能量泛函建模

1.2.1 数学定义

1.2.2 疑问一:什么是泛函?





1.2.3 疑问二:泛函在图像去噪方面的作用?

1.3 求解欧拉-拉格朗日方程

1.4 梯度下降法

1.5 有限差分求近似解

1.6 代码实现

import numpy as np
import cv2 as cv
import matplotlib.pyplot as plt

# 定义 PSNR 计算函数
def calculate_psnr(original, denoised):
    mse = np.mean((original - denoised) ** 2)
    if mse == 0:  # 避免除零
        return float('inf')
    max_pixel = 255.0
    psnr = 20 * np.log10(max_pixel / np.sqrt(mse))
    return psnr

# 定义 TV 去噪(梯度下降法)
def tv_denoise(image, lambda_tv=0.1, iterations=100, tau=0.125):
    u = image.astype(np.float64)
    m, n = u.shape
    for i in range(iterations):
        # 计算梯度
        u_x = np.roll(u, -1, axis=1) - u  # x方向梯度
        u_y = np.roll(u, -1, axis=0) - u  # y方向梯度

        # 计算梯度的模长
        grad_u = np.sqrt(u_x**2 + u_y**2 + 1e-8)  # 避免除零
        
        # 更新u,使用离散梯度下降
        u = u + tau * (np.roll(u_x / grad_u, 1, axis=1) - u_x / grad_u + np.roll(u_y / grad_u, 1, axis=0) - u_y / grad_u) - tau * lambda_tv * (u - image)
    
    return np.clip(u, 0, 255).astype(np.uint8)

# 打开图片并转换为灰度图像
img_dir = r'D:\Document\Experiment\data\image1.jpg'
gray = cv.imread(img_dir, 0)  # 读取图像并转换为灰度
image_array = np.array(gray)

# 定义高斯噪声的参数
mean = 0  # 均值
sigma = 20  # 调低噪声强度(标准差)

# 生成高斯噪声
gaussian_noise = np.random.normal(mean, sigma, image_array.shape)

# 将噪声加入图像
noisy_image = image_array + gaussian_noise

# 将噪声后的图像剪裁到0-255范围内,并转换为uint8
noisy_image_clipped = np.clip(noisy_image, 0, 255).astype(np.uint8)

# 调用 TV 去噪
denoised_image = tv_denoise(noisy_image_clipped, lambda_tv=0.1, iterations=100, tau=0.125)

# 计算原始图像和去噪图像的 PSNR
psnr_noisy = calculate_psnr(image_array, noisy_image_clipped)
psnr_denoised = calculate_psnr(image_array, denoised_image)

# 显示原图、噪声图像和去噪后的图像
plt.figure(figsize=(15, 5))
plt.subplot(1, 3, 1)
plt.title('Original Image')
plt.imshow(image_array, cmap='gray')

plt.subplot(1, 3, 2)
plt.title(f'Noisy Image (PSNR: {psnr_noisy:.2f})')
plt.imshow(noisy_image_clipped, cmap='gray')

plt.subplot(1, 3, 3)
plt.title(f'Denoised Image (PSNR: {psnr_denoised:.2f})')
plt.imshow(denoised_image, cmap='gray')

plt.show()

目前没有分析去噪后PSNR值下降的原因

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐