两个非均值滤波算法(NM)代码
来源:互联网 发布:电子图书数据库读秀 编辑:程序博客网 时间:2024/05/21 18:33
% Non_Local_Means滤波器
%函数输入:
% Nimg: 输入的图像矩阵 + 带噪声的
% PSH: 扩展窗尺寸大小
% WSH: 窗尺寸大小
% Sigma:方差
%函数输出:
% DeNimg: 重构滤波图像
if ~isa(Nimg,'double')
Nimg = double(Nimg)/255;
end
% 图像维数
[Height,Width] = size(Nimg);
u = zeros(Height,Width); % 初始化去噪图像矩阵
M = u; % 初始化权值矩阵
Z = M; % 初始化叠加权值 accumlated weights
% 避免边界效应
PP = padarray(Nimg,[PSH,PSH],'symmetric','both');
PW = padarray(Nimg,[WSH,WSH],'symmetric','both');
% padarray使用
% A =
% 1 3 4
% 2 3 4
% 3 4 5
% B = padarray(A, 2 * [1 1], 0, 'both')
% 0 0 0 0 0 0 0
% 0 0 0 0 0 0 0
% 0 0 1 3 4 0 0
% 0 0 2 3 4 0 0
% 0 0 3 4 5 0 0
% 0 0 0 0 0 0 0
% 0 0 0 0 0 0 0
% 主循环
for dx = -WSH:WSH
for dy = -WSH:WSH
if dx ~= 0 || dy ~= 0
Sd = integral_img(PP,dx,dy); % 插值图像
% 获取对应像素点的平方差矩阵
SDist = Sd(PSH+1:end-PSH,PSH+1:end-PSH)+Sd(1:end-2*PSH,1:end-2*PSH)-Sd(1:end-2*PSH,PSH+1:end-PSH)-Sd(PSH+1:end-PSH,1:end-2*PSH);
% 计算每一个像素点的权值
w = exp(-SDist/(2*Sigma^2));
% 得到相应的噪声点
v = PW((WSH+1+dx):(WSH+dx+Height),(WSH+1+dy):(WSH+dy+Width));
% 更新去噪图像矩阵
u = u+w.*v;
% 更新权值去噪图像矩阵
M = max(M,w);
% 更新叠加权值 accumlated weights
Z = Z+w;
end
end
end
% 重构图像
f = 1;
u = u+f*M.*Nimg;
u = u./(Z+f*M);
DeNimg = u; % 重构去噪图像
function Sd = integral_img(v,dx,dy)
% 根据平方差,插值图像
% 变换计算:tx = vx+dx; ty = vy+dy
t = img_Shift(v,dx,dy);
% 平方差图像
diff = (v-t).^2;
% 沿行插值
Sd = cumsum(diff,1); % 行叠加
% 沿列插值
Sd = cumsum(Sd,2); % 列叠加
function t = img_Shift(v,dx,dy)
% 在xy坐标系下,进行图像变换操作
t = zeros(size(v));
type = (dx>0)*2+(dy>0);
switch type
case 0 % dx<0,dy<0: 向右下方移动
t(-dx+1:end,-dy+1:end) = v(1:end+dx,1:end+dy);
case 1 % dx<0,dy>0: 向左下方移动
t(-dx+1:end,1:end-dy) = v(1:end+dx,dy+1:end);
case 2 % dx>0,dy<0: 向右上方移动
t(1:end-dx,-dy+1:end) = v(dx+1:end,1:end+dy);
case 3 % dx>0,dy>0: 向左上方移动
t(1:end-dx,1:end-dy) = v(dx+1:end,dy+1:end);
end
参考:http://www.ilovematlab.cn/thread-449040-1-1.html
function [output]=NLmeansfilter(input,t,f,h)
[m n]=size(input);
%t:搜索框半径;f:相似框半径;h:滤波频率百分比
Output=zeros(m,n);
input2 = padarray(input,[f f],'symmetric');
%将边缘对称折叠上去
% f :加宽的宽度值
kernel = make_kernel(f); %计算得到一个高斯核,用于后续的计算
kernel = kernel / sum(sum(kernel)); %sum:对矩阵k的每一列求和,k表示矩阵k的总和
h=h*h;
for i=1:m
for j=1:n
i1 = i+ f;
j1 = j+ f;
W1= input2(i1-f:i1+f , j1-f:j1+f);
wmax=0;
average=0;
sweight=0;
rmin = max(i1-t,f+1); %确定相似框的边长,其实可以在代入数据的时候就设置搜索框和边界框边长的大小关系,就不用求最大最小值了
rmax = min(i1+t,m+f); %这段主要是控制不超出索引值
smin = max(j1-t,f+1);
smax = min(j1+t,n+f);
for r=rmin:1:rmax
for s=smin:1:smax
if(r==i1 && s==j1) continue; end;
W2= input2(r-f:r+f , s-f:s+f);
d = sum(sum(kernel.*(W1-W2).*(W1-W2)));
w=exp(-d/h);
if w>wmax
wmax=w;
end
sweight = sweight + w;
average = average + w*input2(r,s);
end
end
average = average + wmax*input2(i1,j1);
sweight = sweight + wmax;
if sweight > 0
output(i,j) = average / sweight;
else
output(i,j) = input(i,j);
end
end
end
function [kernel] = make_kernel(f) %这是一个高斯核
kernel=zeros(2*f+1,2*f+1);
for d=1:f
value= 1 / (2*d+1)^2 ;
for i=-d:d
for j=-d:d
kernel(f+1-i,f+1-j)= kernel(f+1-i,f+1-j) + value ;
end
end
end
kernel = kernel ./ f;
参考自:http://blog.csdn.net/frankgoogle/article/details/52209901#reply
- 两个非均值滤波算法(NM)代码
- 非局部均值滤波算法
- 非局部均值滤波matlab代码理解
- 非局部均值滤波算法的python实现
- 均值滤波快速算法
- openCV之中值滤波&均值滤波(及代码实现)
- 均值滤波代码 C代码
- K均值算法(代码)
- 图像处理之Non-Local Means(NM) 非局部均值
- 滤波算法(均值、中值、最大均值、最大中值、几何均值)
- 图像算法之十二:非局部均值滤波及其Matlab实现
- 深度学习结合非局部均值滤波的图像去噪算法
- 滑动移动均值滤波简单代码实例
- 算法学习笔记之均值滤波法
- 基于积分图的均值滤波算法
- 均值滤波和中值滤波的java代码
- 均值滤波
- 均值滤波
- curl工具介绍和常用命令
- oracle10 RAC节点添加过程
- Java-数据类型转换
- Aspose.words之IReplacingCallback接口的应用
- 阿里云 短信服务实现
- 两个非均值滤波算法(NM)代码
- java中的true,false,null
- XSS跨脚本攻击原理
- gcc的一些选项
- HP-UX操作系统安装配置手册
- 论Ajax async(同步/异步)属性的重要性
- vs2017离线
- Android入门之常用控件
- eclipse新导入的项目经常可以看到“XX cannot be resolved to a type”的报错信息