非局部均值滤波算法的python实现

图像去噪算法
本文介绍了一种基于非局部均值滤波(NL-means)的图像去噪算法,并与中值滤波及OpenCV自带的快速非局部均值去噪算法进行了比较。通过计算峰值信噪比(PSNR),验证了不同去噪方法的效果。
部署运行你感兴趣的模型镜像
#coding:utf8
import cv2
import numpy as np
def psnr(A, B):
    return 10*np.log(255*255.0/(((A.astype(np.float)-B)**2).mean()))/np.log(10)

def double2uint8(I, ratio=1.0):
    return np.clip(np.round(I*ratio), 0, 255).astype(np.uint8)

def make_kernel(f):
    kernel = np.zeros((2*f+1, 2*f+1))
    for d in range(1, f+1):
        kernel[f-d:f+d+1, f-d:f+d+1] += (1.0/((2*d+1)**2))
    return kernel/kernel.sum()

def NLmeansfilter(I, h_=10, templateWindowSize=5,  searchWindowSize=11):
    f = templateWindowSize/2
    t = searchWindowSize/2
    height, width = I.shape[:2]
    padLength = t+f
    I2 = np.pad(I, padLength, 'symmetric')
    kernel = make_kernel(f)
    h = (h_**2)
    I_ = I2[padLength-f:padLength+f+height, padLength-f:padLength+f+width]

    average = np.zeros(I.shape)
    sweight = np.zeros(I.shape)
    wmax =  np.zeros(I.shape)
    for i in range(-t, t+1):
        for j in range(-t, t+1):
            if i==0 and j==0:
                continue
            I2_ = I2[padLength+i-f:padLength+i+f+height, padLength+j-f:padLength+j+f+width]
            w = np.exp(-cv2.filter2D((I2_ - I_)**2, -1, kernel)/h)[f:f+height, f:f+width]
            sweight += w
            wmax = np.maximum(wmax, w)
            average += (w*I2_[f:f+height, f:f+width])
    return (average+wmax*I)/(sweight+wmax)

if __name__ == '__main__':
    I = cv2.imread('lena.jpg', 0)

    sigma = 20.0
    I1 = double2uint8(I + np.random.randn(*I.shape) *sigma)
    print u'噪声图像PSNR',psnr(I, I1)
    R1  = cv2.medianBlur(I1, 5)
    print u'中值滤波PSNR',psnr(I, R1)
    R2 = cv2.fastNlMeansDenoising(I1, None, sigma, 5, 11)
    print u'opencv的NLM算法',psnr(I, R2)
    R3 = double2uint8(NLmeansfilter(I1.astype(np.float), sigma, 5, 11))
    print u'NLM PSNR',psnr(I, R3)
        

您可能感兴趣的与本文相关的镜像

TensorFlow-v2.9

TensorFlow-v2.9

TensorFlow

TensorFlow 是由Google Brain 团队开发的开源机器学习框架,广泛应用于深度学习研究和生产环境。 它提供了一个灵活的平台,用于构建和训练各种机器学习模型

### 非局部均值滤波算法简介 非局部均值(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]。 ### 结论 综上所述,非局部均值滤波器能够有效减少随机噪声的同时保留边缘细节特征。然而需要注意的是,由于涉及大量配对操作,这种方法可能带来较高的时间复杂度,实际部署前需优化性能表现。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值