经典非局部均值滤波(NLM)算法python实现(1)

经典非局部均值滤波(NLM)算法python实现(单通道图像版本)

概述:非局部均值(NL-means)是近年来提出的一项新型的去噪技术。该方法充分利用了图像中的冗余信息,在去噪的同时能最大程度地保持图像的细节特征。基本思想是:当前像素的估计值由图像中与它具有相似邻域结构的像素加权平均得到。

工作原理:请参照参考文献:https://blog.csdn.net/literacy_wang/article/details/106937535

以下是博主根据自己的一些个人理解和网上MATLAB代码翻译过来的代码, 适合单通道的图片场景:

# 传统的非局部均值滤波器
import cv2 
import numpy as np 

# 单通道
# f为相似窗口的半径, t为搜索窗口的半径, h为高斯函数平滑参数(一般取为相似窗口的大小)
def make_kernel(f):
    kernel = np.zeros((2*f+1, 2*f+1), np.float32)
    for d in range(1, f+1):
        kernel[f-d:f+d+1, f-d:f+d+1
### 非局部均值滤波算法简介 非局部均值(Non-Local Means, NLM)是一种用于图像去噪的有效技术。该算法的核心思想在于利用整幅图像中的相似区域来估计当前像素的噪声水平并对其进行平滑处理[^3]。 NLM 的基本假设是:自然图像通常具有重复结构,即在不同位置可能存在类似的纹理或模式。因此,在计算某个像素点的新值时,可以不仅仅依赖于其邻域内的像素,还可以考虑更远距离上的其他像素点及其邻域的信息。 #### 数学表达形式 对于目标像素 \( p \),它的新值可以通过加权平均的方式得到: \[ f(p) = \frac{\sum_{q} w(p,q)f(q)}{\sum_{q}w(p,q)} \] 其中: - \( f(p) \) 表示原始图像中像素 \( p \) 的灰度值; - \( q \) 是另一个像素的位置; - 权重函数 \( w(p,q) \) 定义为两个像素之间相似性的度量,具体定义如下: \[ w(p,q) = e^{-\frac{d^2(N_p,N_q)}{h^2}} \] 这里: - \( d^2(N_p,N_q) \) 表示以 \( p \) 和 \( q \) 为中心的小窗口之间的欧氏平方距离; - 参数 \( h \) 控制权重衰减的速度;较大的 \( h \) 值会使更多不完全匹配的像素参与运算。 #### 实现步骤概述 以下是 Python 中的一个简单实现版本,展示了如何应用此算法去除高斯白噪声的影响: ```python import numpy as np from scipy.ndimage import gaussian_filter def compute_weights(image_patch1, image_patch2, sigma=0.1): """Compute the exponential weight between two patches.""" diff = image_patch1 - image_patch2 norm_squared = np.sum(diff ** 2) return np.exp(-norm_squared / (sigma ** 2)) def non_local_means_denoising(input_image, search_window_size=7, patch_size=5, h=0.8): height, width = input_image.shape[:2] denoised_image = np.zeros_like(input_image) pad_width = max(search_window_size, patch_size) // 2 padded_image = np.pad(input_image, ((pad_width, pad_width), (pad_width, pad_width)), mode='reflect') for i in range(height): for j in range(width): total_weight = 0. weighted_sum = 0. center_i = i + pad_width center_j = j + pad_width reference_patch = padded_image[center_i-patch_size//2:center_i+patch_size//2+1, center_j-patch_size//2:center_j+patch_size//2+1] for k in range(max(0, i-search_window_size//2), min(i+search_window_size//2+1, height)): for l in range(max(0, j-search_window_size//2), min(j+search_window_size//2+1, width)): compare_center_i = k + pad_width compare_center_j = l + pad_width current_patch = padded_image[compare_center_i-patch_size//2:compare_center_i+patch_size//2+1, compare_center_j-patch_size//2:compare_center_j+patch_size//2+1] weight = compute_weights(reference_patch, current_patch, sigma=h*h*gaussian_filter(current_patch, sigma=1).std()) weighted_sum += weight * padded_image[compare_center_i, compare_center_j] total_weight += weight denoised_image[i,j] = weighted_sum / total_weight if total_weight != 0 else input_image[i,j] return denoised_image ``` 上述代码实现了基于补丁比较的基本版 Non-Local Means 方法,并通过调整参数 `h` 可控制平滑程度[^4]。 ### 结论 综上所述,非局部均值滤波器能够有效减少随机噪声的同时保留边缘细节特征。然而需要注意的是,由于涉及大量配对操作,这种方法可能带来较高的时间复杂度,实际部署前需优化性能表现。
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值