积分图像的应用(二):非局部均值去噪(NL-means)
非局部均值去噪(NL-means)一文介绍了NL-means基本算法,同时指出了该算法效率低的问题,本文将使用积分图像技术对该算法进行加速。
假设图像共像个素点,搜索窗口大小
,领域窗口大小
, 计算两个矩形邻域间相似度的时间为
,对于每个像素点需要计算它与搜索窗口内
个像素间的相似度,故NL-means复杂度为
。
经过分析可以发现,该算法可以提高之处只有邻域间相似度的计算,即耗时的操作。基本算法中,每次计算邻域间距离时都需要遍历两个邻域,逐对像素点求差值。
如果我们先构造一个关于像素差值的积分图像:
其中
这样在计算两个邻域和
间的距离时,就可以在常量时间内完成:
这样,整个算法复杂度将降为 。
具体的算法描述可以参考[1]中:
为了降低空间复杂度,上述算法将偏移量作为最外层循环,即每次只需要在一个偏移方向上求取积分图像,并对该积分图像进行处理。而不需要一次性求取出所有积分图像。
程序:
close all;
clear all;
clc
I=double(imread('lena.tif'));
I=I+*randn(size(I));
tic
O1=NLmeans(I,,,);
toc
tic
O2=fastNLmeans(I,,,);
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+,Ds+ds+],'symmetric','both');
PaddedV = padarray(I,[Ds,Ds],'symmetric','both');
average=zeros(m,n);
sweight=average;
wmax=average;
h2=h*h;
d2=(*ds+)^;
for t1=-Ds:Ds
for t2=-Ds:Ds
if(t1==&&t2==)
continue;
end
St=integralImgSqDiff(PaddedImg,Ds,t1,t2);
v = PaddedV(+Ds+t1:end-Ds+t1,+Ds+t2:end-Ds+t2);
w=zeros(m,n);
for i=:m
for j=:n
i1=i+ds+;
j1=j+ds+;
Dist2=St(i1+ds,j1+ds)+St(i1-ds-,j1-ds-)-St(i1+ds,j1-ds-)-St(i1-ds-,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-*Ds;
n1=n-*Ds;
Sd=zeros(m1,n1);
Dist2=(PaddedImg(+Ds:end-Ds,+Ds:end-Ds)-PaddedImg(+Ds+t1:end-Ds+t1,+Ds+t2:end-Ds+t2)).^;
for i=:m1
for j=:n1
if i== && j==
Sd(i,j)=Dist2(i,j);
elseif i== && j~=
Sd(i,j)=Sd(i,j-)+Dist2(i,j);
elseif i~= && j==
Sd(i,j)=Sd(i-,j)+Dist2(i,j);
else
Sd(i,j)=Dist2(i,j)+Sd(i-,j)+Sd(i,j-)-Sd(i-,j-);
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+,Ds+ds+],'symmetric','both');
PaddedV = padarray(I,[Ds,Ds],'symmetric','both');
average=zeros(m,n);
wmax=average;
sweight=average;
h2=h*h;
d=(*ds+)^;
for t1=-Ds:Ds
for t2=-Ds:Ds
if(t1==&&t2==)
continue;
end
Sd=integralImgSqDiff(PaddedImg,Ds,t1,t2);
SqDist2=Sd(*ds+:end-,*ds+:end-)+Sd(:end-*ds-,:end-*ds-)...
-Sd(*ds+:end-,:end-*ds-)-Sd(:end-*ds-,*ds+:end-);
SqDist2=SqDist2/d;
w=exp(-SqDist2/h2);
v = PaddedV(+Ds+t1:end-Ds+t1,+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(+Ds:end-Ds,+Ds:end-Ds)-PaddedImg(+Ds+t1:end-Ds+t1,+Ds+t2:end-Ds+t2)).^;
Sd = cumsum(Dist2,);
Sd = cumsum(Sd,);
使用上述fastNLmeans2函数对该lena图处理仅耗时0.416442s。
参考:
[1]FromentJ. Parameter-Free Fast Pixelwise Non-Local Means Denoising[J]. Image ProcessingOn Line, 2014, 4: 300-326
积分图像的应用(二):非局部均值去噪(NL-means)的更多相关文章
- 非局部均值去噪(NL-means)
非局部均值(NL-means)是近年来提出的一项新型的去噪技术.该方法充分利用了图像中的冗余信息,在去噪的同时能最大程度地保持图像的细节特征.基本思想是:当前像素的估计值由图像中与它具有相似邻域结构的 ...
- 非局部均值(Nonlocal-Mean)
转载自网站:http://www.cnblogs.com/luo-peng/p/4785922.html 非局部均值去噪(NL-means) 非局部均值(NL-means)是近年来提出的一项新型的 ...
- NLM非局部均值算法相关
NLM原文: 基于图像分割的非局部均值去噪算法 基于图像分割的非局部均值去噪算法_百度文库 https://wenku.baidu.com/view/6a51abdfcd22bcd126fff705c ...
- 非局部均值滤波算法的python实现
如题,比opencv自带的实现效果好 #coding:utf8 import cv2 import numpy as np def psnr(A, B): return 10*np.log(255*2 ...
- OpenCV2:等间隔采样和局部均值的图像缩小
图像的缩小从物理意义上来说,就是将图像的每个像素的大小缩小相应的倍数.但是,改变像素的物理尺寸显然不是那么容易的,从数字图像处理的角度来看,图像的缩小实际就是通过减少像素个数来实现的.显而易见的,减少 ...
- 积分图像的应用(一):局部标准差 分类: 图像处理 Matlab 2015-06-06 13:31 137人阅读 评论(0) 收藏
局部标准差在图像处理邻域具有广泛的应用,但是直接计算非常耗时,本文利用积分图像对局部标准差的计算进行加速. 局部标准差: 标准差定义如下(采用统计学中的定义,分母为): 其中. 为了计算图像的局部标准 ...
- 二十、Linux 进程与信号---非局部跳转
20.1 setjmp 和 longjmp 函数 20.1.1 函数介绍 #include <setjmp.h> int setjmp(jmp_buf env); 函数功能:设置非局部跳转 ...
- CVPR2020:基于自适应采样的非局部神经网络鲁棒点云处理(PointASNL)
CVPR2020:基于自适应采样的非局部神经网络鲁棒点云处理(PointASNL) PointASNL: Robust Point Clouds Processing Using Nonlocal N ...
- 【转】浅析C语言的非局部跳转:setjmp和longjmp
转自 http://www.cnblogs.com/lienhua34/archive/2012/04/22/2464859.html C语言中有一个goto语句,其可以结合标号实现函数内部的任意跳转 ...
随机推荐
- oracle隐含参数的查看与修改
v$parameter视图中查询参数的时候其实都是通过x$ksppi和x$ksppcv这两个内部视图中得到的. 1. 可以通过如下方式查询当前实例的所有隐含参数: col name for a30 ...
- 安装ORACLE时在Linux上设置内核参数的含义
前两天看到一篇Redhat官方的Oracle安装文档,对于Linux内核参数的修改描述的非常清晰. 安装Oracle之前,除了检查操作系统的硬件和软件是否满足安装需要之外,一个重点就是修改内核参数,其 ...
- BZOJ2733:[HNOI2012]永无乡
浅谈线段树合并:https://www.cnblogs.com/AKMer/p/10251001.html 题目传送门:https://lydsy.com/JudgeOnline/problem.ph ...
- Centos下Yum安装PHP5.5
默认的版本太低了,手动安装有一些麻烦,想采用Yum安装的可以使用下面的方案: 1.检查当前安装的PHP包 yum list installed | grep php 如果有安装的PHP包,先删除他们 ...
- 转:删除redis所有KEY
转自:http://ssuupv.blog.163.com/blog/static/1461567220135610456193/ 批量删除Key Redis 中有删除单个 Key 的指令 DEL,但 ...
- SQL 常用语句收集
1.UPDATE 表名称 SET 列名称 = 新值 WHERE 列名称 = 某值 2.SELECT * FROM TableA INNER JOIN TableB ON TableA.name = T ...
- Python-Redis的List操作
Redis列表是简单的字符串列表,一个列表可以包含超过40亿个元素 lpush(name,values):在name对应的list中添加元素,每个新的元素都添加到列表的最左边 rpush(name, ...
- SharePoint Project Server List 列表CURD操作使用rest api接口
//#region 界面交互代码 var issuesUtils = issuesUtils || {}; (function () { /** * 点击问题提处理方案按钮事件 */ issuesUt ...
- 使用python+requests对接口进行测试
import unittestimport requestsimport json class Login(unittest.TestCase): def setUp(self): self.base ...
- ASPX 关闭子窗口后自动更新父窗口
Response.Write("<script language:javascript>javascript:window.close();</script>&quo ...