两个非均值滤波算法(NM)代码

news/2024/7/21 5:09:13 标签: 图像处理, 算法
function DeNimg = Non_Local_Means(Nimg,PSH,WSH,Sigma)
% 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


http://www.niftyadmin.cn/n/1714064.html

相关文章

KafkaToturial

Brief Tutorial for Kafka Modules 原文 -> Github [转载请注明&#xff01;] Author: Shen Wenrui Email: Thomas.shen3904qq.com 1.Zookeeper: 1.1 Installation: Zookeeper下载地址:https://mirrors.tuna.tsinghua.edu.cn/apache/zookeeper/stable/ tar -zxf zook…

个人设计web前端大作业~响应式游戏网站源码(HTML+CSS+Bootstrap)

HTML期末大作业课程设计游戏主题html5网页~响应式游戏网站(HTMLCSSBootstrap) ~个人设计web前端大作业 临近期末, 你还在为HTML网页设计结课作业,老师的作业要求感到头大&#xff1f;HTML网页作业无从下手&#xff1f;网页要求的总数量太多&#xff1f;没有合适的模板&#xf…

投稿会议论文的近期常用网站信号与图像处理国际会议

1、科学网 http://meeting.sciencenet.cn/ 2、ICSIP 信号与图像处理国际会议 http://www.icsip.org/chinese.html 3、VS 下载资源 MSDN http://www.itellyou.cn/

HTML期末大作业~个人图片资源网页设计共5个页面(HTML+CSS+JavaScript)

HTML期末大作业~制作个人图片资源网页5个页面(HTMLCSSJavaScript) 临近期末, 你还在为HTML网页设计结课作业,老师的作业要求感到头大&#xff1f;HTML网页作业无从下手&#xff1f;网页要求的总数量太多&#xff1f;没有合适的模板&#xff1f;等等一系列问题。你想要解决的问…

nyoj阶乘之和

&#xfeff;&#xfeff; /*阶乘之和 时间限制&#xff1a;3000 ms | 内存限制&#xff1a;65535 KB 难度&#xff1a;3 描述 给你一个非负数整数n&#xff0c;判断n是不是一些数&#xff08;这些数不允许重复使用&#xff0c;且为正数&#xff09;的阶乘之和&#xff0c; …

计算机视觉学习之CVPR系列文章

CVPR2016系列文章及其代码&#xff1a;http://blog.csdn.net/mydear_11000/article/details/51915489

nyoj269VF

&#xfeff;&#xfeff; /*VF 时间限制&#xff1a;1000 ms | 内存限制&#xff1a;65535 KB 难度&#xff1a;2 描述 Vasya is the beginning mathematician. He decided to make an important contribution to the science and to become famous all over the world. Bu…

qt中限制QLineEdit的输入范围

1、输入整数部分 lineEdit->setValidator(new QIntValidator(1, 1000, this)); //但是仍然能输入0000000 2、简单的小数输入 lineEdit->setValidator(new QDoubleValidator(-180.0,180.0,6,this)); 3、使用正则表达式输入 1&#xff09;输入(0,1) 两位小数 QRe…