积分图像的应用(二):非局部均值去噪(NL-means)

非局部均值去噪(NL-means)一文介绍了NL-means基本算法,同时指出了该算法效率低的问题,本文将使用积分图像技术对该算法进行加速。

假设图像共像个素点,搜索窗口大小,领域窗口大小, 计算两个矩形邻域间相似度的时间为,对于每个像素点需要计算它与搜索窗口内个像素间的相似度,故NL-means复杂度为 。

经过分析可以发现,该算法可以提高之处只有邻域间相似度的计算,即耗时的操作。基本算法中,每次计算邻域间距离时都需要遍历两个邻域,逐对像素点求差值。

如果我们先构造一个关于像素差值的积分图像:

其中

这样在计算两个邻域和  间的距离时,就可以在常量时间内完成:

这样,整个算法复杂度将降为 。

具体的算法描述可以参考[1]中:

为了降低空间复杂度,上述算法将偏移量作为最外层循环,即每次只需要在一个偏移方向上求取积分图像,并对该积分图像进行处理。而不需要一次性求取出所有积分图像。

程序:

close all;
clear all;
clc
I=double(imread(‘lena.tif‘));
I=I+10*randn(size(I));
tic
O1=NLmeans(I,2,5,10);
toc
tic
O2=fastNLmeans(I,2,5,10);
toc
figure;
imshow([I,O1,O2],[]);
function DenoisedImg=fastNLmeans(I,ds,Ds,h)
%I:含噪声图像
%ds:邻域窗口半径
%Ds:搜索窗口半径
%h:高斯函数平滑参数
%DenoisedImg:去噪图像
I=double(I);
[m,n]=size(I);
PaddedImg = padarray(I,[Ds+ds+1,Ds+ds+1],‘symmetric‘,‘both‘);
PaddedV = padarray(I,[Ds,Ds],‘symmetric‘,‘both‘);
average=zeros(m,n);
sweight=average;
wmax=average;
h2=h*h;
d2=(2*ds+1)^2;
for t1=-Ds:Ds
    for t2=-Ds:Ds
        if(t1==0&&t2==0)
            continue;
        end
        St=integralImgSqDiff(PaddedImg,Ds,t1,t2);
        v = PaddedV(1+Ds+t1:end-Ds+t1,1+Ds+t2:end-Ds+t2);
        w=zeros(m,n);
        for i=1:m
            for j=1:n
                i1=i+ds+1;
                j1=j+ds+1;
                Dist2=St(i1+ds,j1+ds)+St(i1-ds-1,j1-ds-1)-St(i1+ds,j1-ds-1)-St(i1-ds-1,j1+ds);
                Dist2=Dist2/d2;
                w(i,j)=exp(-Dist2/h2);
                sweight(i,j)=sweight(i,j)+w(i,j);
                average(i,j)=average(i,j)+w(i,j)*v(i,j);
            end
        end
        wmax=max(wmax,w);
    end
end
average=average+wmax.*I;
sweight=sweight+wmax;
DenoisedImg=average./sweight;

function Sd = integralImgSqDiff(PaddedImg,Ds,t1,t2)
%PaddedImg:边缘填充后的图像
%Ds:搜索窗口半径
%(t1,t2):偏移量
%Sd:积分图像
[m,n]=size(PaddedImg);
m1=m-2*Ds;
n1=n-2*Ds;
Sd=zeros(m1,n1);
Dist2=(PaddedImg(1+Ds:end-Ds,1+Ds:end-Ds)-PaddedImg(1+Ds+t1:end-Ds+t1,1+Ds+t2:end-Ds+t2)).^2;
for i=1:m1
    for j=1:n1
         if i==1 && j==1
             Sd(i,j)=Dist2(i,j);
         elseif i==1 && j~=1
             Sd(i,j)=Sd(i,j-1)+Dist2(i,j);
         elseif i~=1 && j==1
             Sd(i,j)=Sd(i-1,j)+Dist2(i,j);
         else
             Sd(i,j)=Dist2(i,j)+Sd(i-1,j)+Sd(i,j-1)-Sd(i-1,j-1);
         end
     end
end

结果:

三幅图像依次是含噪声原图,原始NL-means算法去噪结果、使用积分图像加速的NL-means算法去噪结果。对于256*256的lena图,原始算法耗时 36.251389s,使用积分图像加速的算法耗时 4.647372s。

当然,对于Matlab而言,若充分利用它的函数和矩阵操作,可进一步在编程上加速:

function DenoisedImg=fastNLmeans2(I,ds,Ds,h)
I=double(I);
[m,n]=size(I);
PaddedImg = padarray(I,[Ds+ds+1,Ds+ds+1],‘symmetric‘,‘both‘);
PaddedV = padarray(I,[Ds,Ds],‘symmetric‘,‘both‘);
average=zeros(m,n);
wmax=average;
sweight=average;
h2=h*h;
d=(2*ds+1)^2;
for t1=-Ds:Ds
    for t2=-Ds:Ds
        if(t1==0&&t2==0)
            continue;
        end
        Sd=integralImgSqDiff(PaddedImg,Ds,t1,t2);
        SqDist2=Sd(2*ds+2:end-1,2*ds+2:end-1)+Sd(1:end-2*ds-2,1:end-2*ds-2)...
               -Sd(2*ds+2:end-1,1:end-2*ds-2)-Sd(1:end-2*ds-2,2*ds+2:end-1);
        SqDist2=SqDist2/d;
        w=exp(-SqDist2/h2);
        v = PaddedV(1+Ds+t1:end-Ds+t1,1+Ds+t2:end-Ds+t2);
        average=average+w.*v;
        wmax=max(wmax,w);
        sweight=sweight+w;
    end
end
average=average+wmax.*I;
average=average./(wmax+sweight);
DenoisedImg = average;

function Sd = integralImgSqDiff(PaddedImg,Ds,t1,t2)
Dist2=(PaddedImg(1+Ds:end-Ds,1+Ds:end-Ds)-PaddedImg(1+Ds+t1:end-Ds+t1,1+Ds+t2:end-Ds+t2)).^2;
Sd = cumsum(Dist2,1);
Sd = cumsum(Sd,2);

使用上述fastNLmeans2函数对该lena图处理仅耗时0.416442s。

参考:

[1]FromentJ. Parameter-Free Fast Pixelwise Non-Local Means Denoising[J]. Image ProcessingOn Line, 2014, 4: 300-326

时间: 2024-10-12 03:42:44

积分图像的应用(二):非局部均值去噪(NL-means)的相关文章

非局部均值去噪(NL-means)

非局部均值(NL-means)是近年来提出的一项新型的去噪技术.该方法充分利用了图像中的冗余信息,在去噪的同时能最大程度地保持图像的细节特征.基本思想是:当前像素的估计值由图像中与它具有相似邻域结构的像素加权平均得到. 理论上,该算法需要在整个图像范围内判断像素间的相似度,也就是说,每处理一个像素点时,都要计算它与图像中所有像素点间的相似度.但是考虑到效率问题,实现的时候,会设定两个固定大小的窗口:搜索窗口和邻域窗口.邻域窗口在搜索窗口中滑动,根据邻域间的相似性确定像素的权值. 下图是NL-me

非局部均值(Nonlocal-Mean)

转载自网站:http://www.cnblogs.com/luo-peng/p/4785922.html 非局部均值去噪(NL-means) 非局部均值(NL-means)是近年来提出的一项新型的去噪技术.该方法充分利用了图像中的冗余信息,在去噪的同时能最大程度地保持图像的细节特征.基本思想是:当前像素的估计值由图像中与它具有相似邻域结构的像素加权平均得到. 理论上,该算法需要在整个图像范围内判断像素间的相似度,也就是说,每处理一个像素点时,都要计算它与图像中所有像素点间的相似度.但是考虑到效率

图像处理之积分图应用四(基于局部均值的图像二值化算法)

图像处理之积分图应用四(基于局部均值的图像二值化算法) 基本原理 均值法,选择的阈值是局部范围内像素的灰度均值(gray mean),该方法的一个变种是用常量C减去均值Mean,然后根据均值实现如下操作: pixel = (pixel > (mean - c)) ? object : background 其中默认情况下参数C取值为0.object表示前景像素,background表示背景像素. 实现步骤 1. 彩色图像转灰度图像 2. 获取灰度图像的像素数据,预计算积分图 3. 根据输入的参数

图像算法之十二:非局部均值滤波及其Matlab实现

保边去噪算法之二: 首先谈一下什么是非局部均值滤波.在此之前,我们先来看一下均值滤波的原理. 均值滤波 均值滤波的计算非常简单,将图像像素点灰度记录在数组中,然后设置方框半径的值,然后将方框中的所有点的像素求和取平均,得到的结果就是均值滤波后对应像素点的灰度值. 优点: 计算很快而且简单 从算法可以看出,只是求了平均,并没有很复杂的计算 缺点: 得到的图像很模糊 当方框的半径越大,得到的图像中那些变化较大的地方(边缘)计算后变化就越小,即边缘不明显,即模糊 非局部均值滤波 非局部均值滤波的基本原

OpenCV2:等间隔采样和局部均值的图像缩小

图像的缩小从物理意义上来说,就是将图像的每个像素的大小缩小相应的倍数.但是,改变像素的物理尺寸显然不是那么容易的,从数字图像处理的角度来看,图像的缩小实际就是通过减少像素个数来实现的.显而易见的,减少图像的像素会造成图像信息丢失.为了在缩小图像的同时,保持原图的概貌特征不丢失,从原图中选择的像素方法是非常重要的.本文主要介绍基于等间隔采样的图像缩小和基于局部均值的图像缩小以及其在OpenCV2的实现. 基于等间隔采样的图像缩小 这种图像缩小算法,通过对原图像像素进行均匀采样来保持所选择到的像素仍

积分图像的应用(一):局部标准差

局部标准差在图像处理邻域具有广泛的应用,但是直接计算非常耗时,本文利用积分图像对局部标准差的计算进行加速. 局部标准差: 标准差定义如下(采用统计学中的定义,分母为): 其中. 为了计算图像的局部标准差,首先设定局部区域的大小为 ,则局部区域的像素点个数 . 对标准差的公式进行化简: 因,故: 可以看出,局部标准差计算中需要对图像与进行局部求和操作,即和. 我们可以先分别计算出图像和的积分图像.,这样就能在常量时间计算出上述的局部和. 时间复杂度: 图像中共个像素点,每个局部区域共有个像素点,直

第5章 进程环境(5)_非局部跳转

6. 非局部跳转 (1)setjmp和longjmp语句 头文件 #include<setjmp.h> 函数 int* setjmp(jum_buf env); 返回值 直接调用返回0,若从longjmp调用返回则返回非0值 功能 设置非局部跳转的跳转点   函数 void longjmp(jmp_buf env, int val); 功能 进行非局部转转,val为返回值 参数 env:一个特殊类型jmp_buf.这一数据类型是某种形式的数组,其中存放在调用longjmp时能用来恢复栈状态的信

VB6之图像灰度与二值化

老代码备忘,我对图像处理不是太懂. 注:部分代码引援自网上,话说我到底自己写过什么代码... Private Declare Function GetBitmapBits Lib "gdi32" (ByVal hbitmap As Long, _ ByVal dwCount As Long, _ lpBits As Any) As Long Private Declare Function SetBitmapBits Lib "gdi32" (ByVal hbitm

【练习6.14】积分图像cvIntegral及使用积分图的性质找横向和纵向边,IplImage结构中widthStep细节

提纲 题目要求 程序代码 结果图片 要言妙道 题目要求: 加载一副灰度图,得到它的积分图.利用积分图的性质找到图像里的横向和纵向边缘. 利用细长的矩形,在适当的位置减去或加上它们. 备注:边缘查找尚未加入代码 程序代码: 1 // OpenCVExerciseTesting.cpp : 定义控制台应用程序的入口点. 2 // 3 //D:\\Work\\Work_Programming\\Source\\Image\\lena.jpg 4 5 #include "stdafx.h" 6