NAFSM中值滤波器讲解与实现

article/2025/8/27 16:20:48

去年大三时课上,医学图像处理老师讲解了这个算法,当时布置的作业就是实现这个中值滤波器,今天突然从一篇论文中看到过类似这种思想,就又想起来了,发现网上对这个算法的讲解很少,那我就在这分享一下咯!下面是原论文:
K. K. V. Toh and N. A. Mat Isa, “Noise Adaptive Fuzzy Switching Median Filter for Salt-and-Pepper Noise Reduction,” in IEEE Signal Processing Letters, vol. 17, no. 3, pp. 281-284, March 2010.,链接:https://ieeexplore.ieee.org/document/5356178

接下来我将从我对该算法理解、算法实现、算法MATLAB代码、实验报告这个顺序进行我的讲解,希望能帮助到一些人。
一、NAFSM算法理解:
首先发一张我的总结:

NAFSM中值滤波器原理

第一步:是一个二值化处理,对于图像像素灰度值最大和最小当做椒盐噪声,该像素值变成0。
注意图中公式N(i,j)和X(i,j)的区别,这对于理解后面推导很重要,其中N代表二值化后的矩阵,值为1的像素代表该点不是噪声,为0的像素代表该点为噪声点,而对于X则还是原图的灰度值,后面M代表准恢复图像像素灰度值,Y代表最后处理后的图像像素灰度值大小。
第二步:定义一个矩形框,图中s即代表矩形框的大小参数,如果s=1,代表矩形框大小为33;如果s=2,代表矩形框大小为55,以此类推;
第三步:因为对于处理这类噪声,主要难点就是噪声点灰度大小恢复的问题,作者考虑当在该像素点矩形框内,有存在不是噪声点的点,也就是图片中G的大小不为0,则直接可以提取矩形框内那些不为0的点(非噪声像素点)灰度值的中值作为该点灰度值;
第四步:然而,如果发现矩形框内都是噪声点,也就是矩形框内的N(i,j)都为0,这个时候就需要将矩形框扩大,比如s=1,变成s=2,继续第二步,如果最后发现s=3,也就是77矩形框内结果还是都为噪声点,即G=0,则直接将该点灰度值定义为其33框内,左上角四个像素灰度值的中值(这里解释一下,由于一张图处理一般都是从左上角像素开始,所以这里就假设了正在处理的像素点之前的像素点都已经获得比较靠谱的灰度值大小,所以这里就只选取图中几个像素点灰度大小的中值);
第五步:经过前面几步,至此,M的大小已全部确定,但是这里作者没有直接取M值作为最后处理结果,作者对原始灰度图像计算33矩形框内与中心点灰度值绝对值相差最大值;
第六步:通过一个函数计算F值大小,可参考下图理解:
在这里插入图片描述
结合图中那个求F公式可以知道,其主要思想是:当原始图像3
3矩形框内有像素灰度差异比较大时,认为这个点灰度可信度比较低,也即是F为1,对应于Y值就是不考虑X(原始灰度)大小,当矩形框内像素灰度值差异很小时,认为这点可信度很高(因为如果框内存在椒盐噪声,则必为0或者225,大概率两者都有,所以这个时候值只会很大,不会很小),这个时候F就为0,也就是相信X值大小,同理可理解中间那段(如上图中间那段呈线性变化)。我在matlab程序里选取的T1和T2值分别为30和60,F值是用来衡量M与真实值之间误差;
第七步:最后通过公式求出Y,即最后结果。

二、算法实现
这是matlab上运行部分结果图:
加10%椒盐噪声:
在这里插入图片描述

加20%椒盐噪声

在这里插入图片描述
加50%椒盐噪声:在这里插入图片描述
加70%椒盐噪声:在这里插入图片描述
加90%椒盐噪声:
在这里插入图片描述
可以看到,NAFSM滤波器效果非常好,碾压普通中值滤波器。

三、MATLAB代码:
1、原始代码

clear
[Im,map]=imread('lena.gif');
J=ind2gray(Im, map);
I= imnoise(J,'salt & pepper',0.5);%加入椒盐噪声
[m n]=size(I);
N=zeros(m,n);%定义一个二值图空矩阵
for i=1:1:m %确定图像二值图,将灰度值为0或者255的像素定义为椒盐噪声,二值图大小为0for j=1:1:nif I(i,j)==255||I(i,j)==0N(i,j)=0;elseN(i,j)=1;endend
end
s=input('请输入大小为s*s的矩形窗,s=');
G=zeros(m,n);%定义一用来保存矩形窗内二值总大小的矩阵
for i=1:1:m%计算矩形窗内各像素大小,并且求预恢复值M(i,j) for j=1:1:nW=zeros(s,s);%定义一个空的矩形窗for li=1:1:sfor lj=1:1:sif (i+li-(s+1)/2)<=0||(j+lj-(s+1)/2)<=0||(i+li-(s+1)/2)>m||(j+lj-(s+1)/2)>n%判断是否超出原始图像范围continue;endW(li,lj)=N(i+li-(s+1)/2,j+lj-(s+1)/2);%获取矩形窗内数据endendG(i,j)=sum(sum(W));z=s;for k=s:2:5if G(i,j)==0z=k+2;W1=zeros(z,z);%定义一个空的矩形窗for li=1:1:zfor lj=1:1:zif (i+li-(z+1)/2)<=0||(j+lj-(z+1)/2)<=0||(i+li-(z+1)/2)>m||(j+lj-(z+1)/2)>n%判断是否超出原始图像范围continue;endW1(li,lj)=N(i+li-(z+1)/2,j+lj-(z+1)/2);%获取矩形窗内数据endendG(i,j)=sum(sum(W1));if G(i,j)==0continue;elsebreak;endelsebreak;endendif z==7M(i,j)=median(I(i-1,j-1),I(i,j-1),I(i+1,j-1),I(i-1,j));
%            M(i,j)=I(i,j);continue;endW2=zeros(1,G(i,j));nn=1;for i1=1:1:zfor j1=1:1:zif (i+i1-(z+1)/2)<=0||(j+j1-(z+1)/2)<=0||(i+i1-(z+1)/2)>m||(j+j1-(z+1)/2)>n%判断是否超出原始图像范围continue;      elseif N(i+i1-(z+1)/2,j+j1-(z+1)/2)==1W2(nn)=I(i+i1-(z+1)/2,j+j1-(z+1)/2);nn=nn+1;endendendM(i,j)=median(W2);end
end
W3=zeros(3,3);
D=zeros(m,n);
for i=1:1:mfor j=1:1:nL=zeros(3,3);%定义一个m*n的矩形窗for li=1:1:3for lj=1:1:3if (i+li-(3+1)/2)<=0||(j+lj-(3+1)/2)<=0||(i+li-(3+1)/2)>m||(j+lj-(3+1)/2)>n%判断是否超出原始图像范围continue;endL(li,lj)=I(i+li-(3+1)/2,j+lj-(3+1)/2);%获取矩形窗内数据endendd=zeros(1,9);ii=1;for i1=1:1:3for j1=1:1:3d(ii)=abs(L(i1,j1)-L(2,2));ii=ii+1;endendD(i,j)=max(d);end
end
F=zeros(m,n);
T1=20;
T2=60;
for i=1:1:mfor j=1:1:nif D(i,j)<T1F(i,j)=0;elseif D(i,j)>=T1&&D(i,j)<T2F(i,j)=(D(i,j)-T1)/(T2-T1);elseF(i,j)=1;endend
end
Y=zeros(m,n);
for i=1:1:mfor j=1:1:nY(i,j)=(1-F(i,j))*I(i,j)+F(i,j)*M(i,j);end
end
figure(1)
subplot(2,2,1)
imshow(J);
title('原始图像');
subplot(2,2,2)
imshow(I);
title('加入椒盐噪声后的图像');
subplot(2,2,3)
T=Median_filter(I,s,s);
T=uint8(T);
imshow(T);
title('普通中值滤波函数滤波后图像') 
subplot(2,2,4)
Y=uint8(Y);
imshow(Y);
title('NAFSM滤波器滤波后的图像'); 
function [T]=Median_filter(I,m,n)
[M,N]=size(I);
T=zeros(M,N);
for i=1:1:Mfor j=1:1:NL=zeros(m,n);%定义一个m*n的矩形窗for li=1:1:mfor lj=1:1:nif (i+li-(m+1)/2)<=0||(j+lj-(n+1)/2)<=0||(i+li-(m+1)/2)>M||(j+lj-(n+1)/2)>N%判断是否超出原始图像范围continue;endL(li,lj)=I(i+li-(m+1)/2,j+lj-(n+1)/2);%获取矩形窗内数据endendT(i,j)=median(median(L));%求矩形窗内中值end
end
end

经过qq_50872053提醒,之前代码有点不完美,具体:
(1)、步骤4中,G=0时,应该取的是每次都更新后的值,但是这里一直取得是原始未处理图像数据
(2)、之前没有考虑i,j循环顺序,即考虑先从图片横轴开始处理还是纵轴开始处理
新的修改后代码如下(实际效果有进一步提升):

2、最新版代码

clear
[Im,map]=imread('lena.gif');
J=ind2gray(Im, map);
J_noise= imnoise(J,'salt & pepper',0.90);%加入椒盐噪声
I = J_noise;
[m n]=size(I);
N=zeros(m,n);%定义一个二值图空矩阵
for i=1:1:m %确定图像二值图,将灰度值为0或者255的像素定义为椒盐噪声,二值图大小为0for j=1:1:nif I(i,j)==255||I(i,j)==0N(i,j)=0;elseN(i,j)=1;endend
end
s=input('请输入大小为s*s的矩形窗,s=');
G=zeros(m,n);%定义一用来保存矩形窗内二值总大小的矩阵
for j=1:1:n%计算矩形窗内各像素大小,并且求预恢复值M(i,j) for i=1:1:mW=zeros(s,s);%定义一个空的矩形窗for li=1:1:sfor lj=1:1:sif (i+li-(s+1)/2)<=0||(j+lj-(s+1)/2)<=0||(i+li-(s+1)/2)>m||(j+lj-(s+1)/2)>n%判断是否超出原始图像范围continue;endW(li,lj)=N(i+li-(s+1)/2,j+lj-(s+1)/2);%获取矩形窗内数据endendG(i,j)=sum(sum(W));z=s;for k=s:2:5if G(i,j)==0z=k+2;W1=zeros(z,z);%定义一个空的矩形窗for li=1:1:zfor lj=1:1:zif (i+li-(z+1)/2)<=0||(j+lj-(z+1)/2)<=0||(i+li-(z+1)/2)>m||(j+lj-(z+1)/2)>n%判断是否超出原始图像范围continue;endW1(li,lj)=N(i+li-(z+1)/2,j+lj-(z+1)/2);%获取矩形窗内数据endendG(i,j)=sum(sum(W1));if G(i,j)==0continue;elsebreak;endelsebreak;endendif z==7 && G(i,j)==0if (i-1)<=0||(j-1)<=0||(i+1)>m||(j+1)>n %判断是否超出原始图像范围continue;  elseM(i,j)=median([I(i-1,j-1),I(i,j-1),I(i+1,j-1),I(i-1,j)]);endendW2=zeros(1,G(i,j));nn=1;for i1=1:1:zfor j1=1:1:zif (i+i1-(z+1)/2)<=0||(j+j1-(z+1)/2)<=0||(i+i1-(z+1)/2)>m||(j+j1-(z+1)/2)>n%判断是否超出原始图像范围continue;      elseif N(i+i1-(z+1)/2,j+j1-(z+1)/2)==1W2(nn)=I(i+i1-(z+1)/2,j+j1-(z+1)/2);nn=nn+1;endendendM(i,j)=median(W2);W3=zeros(3,3);
D=zeros(m,n);
L=zeros(3,3);%定义一个m*n的矩形窗
for li=1:1:3for lj=1:1:3if (i+li-(3+1)/2)<=0||(j+lj-(3+1)/2)<=0||(i+li-(3+1)/2)>m||(j+lj-(3+1)/2)>n%判断是否超出原始图像范围continue;endL(li,lj)=I(i+li-(3+1)/2,j+lj-(3+1)/2);%获取矩形窗内数据end
end
d=zeros(1,9);
ii=1;
for i1=1:1:3for j1=1:1:3d(ii)=abs(L(i1,j1)-L(2,2));ii=ii+1;end
end
D(i,j)=max(d);F=zeros(m,n);
T1=20;
T2=60;
if D(i,j)<T1F(i,j)=0;
elseif D(i,j)>=T1&&D(i,j)<T2F(i,j)=(D(i,j)-T1)/(T2-T1);
elseF(i,j)=1;
end% Y=zeros(m,n);
% Y(i,j)=(1-F(i,j))*I(i,j)+F(i,j)*M(i,j);
I(i,j) = (1-F(i,j))*I(i,j)+F(i,j)*M(i,j);end
end        figure(1)
subplot(2,2,1)
imshow(J);
title('原始图像');
subplot(2,2,2)
imshow(J_noise);
title('加入椒盐噪声后的图像');
subplot(2,2,3)
T=Median_filter(J_noise,s,s);
T=uint8(T);
imshow(T);
title('普通中值滤波函数滤波后图像') 
subplot(2,2,4)
Y=uint8(I);
imshow(I);
title('NAFSM滤波器滤波后的图像'); 
function [T]=Median_filter(I,m,n)
[M,N]=size(I);
T=zeros(M,N);
for i=1:1:Mfor j=1:1:NL=zeros(m,n);%定义一个m*n的矩形窗for li=1:1:mfor lj=1:1:nif (i+li-(m+1)/2)<=0||(j+lj-(n+1)/2)<=0||(i+li-(m+1)/2)>M||(j+lj-(n+1)/2)>N%判断是否超出原始图像范围continue;endL(li,lj)=I(i+li-(m+1)/2,j+lj-(n+1)/2);%获取矩形窗内数据endendT(i,j)=median(median(L));%求矩形窗内中值end
end
end    

加90%椒盐噪声(修改后):
在这里插入图片描述
可以发现,明显比之前效果要更好

对于本次实验报告、图片和源matlab代码,可以去我主页下载附件!!!!!!!!!!!
转载请注明出处,谢谢


http://chatgpt.dhexx.cn/article/DydakH1J.shtml

相关文章

中值滤波器处理椒盐噪声

clc; close all; clear all; %读取原始图像 im imread(‘Fig0318(b)(ckt-board-slt-pep-both-0pt2).tif’); im_noise_salt imnoise(im,‘salt & pepper’,0.05); % 加入椒盐噪声 % im_noise_gaussian imnoise(im,‘gaussian’); %定义邻域尺寸 n1 2; m1 2n11; n2 2;…

使用中值滤波器对图像降噪

中值滤波器&#xff1a; 基于排序统计理论的一种能有效抑制噪声的非线性平滑滤波信号处理技术。中值滤波的特点即是首先确定一个以某个像素为中心点的邻域&#xff0c;一般为方形邻域&#xff0c;也可以为圆形、十字形等等&#xff0c;然后将邻域中各像素的灰度值排序&#xff…

【OpenCV 例程 300 篇】101. 自适应中值滤波器

专栏地址&#xff1a;『youcans 的 OpenCV 例程 300篇 - 总目录』 【第 7 章&#xff1a;图像复原与重建】 100. 自适应局部降噪滤波器 101. 自适应中值滤波器 102. 陷波带阻滤波器的传递函数 【youcans 的 OpenCV 例程 300 篇】101. 自适应中值滤波器 3.8 自适应中值滤波器&am…

python实现自适应中值滤波器

目录 原理&#xff08;冈萨雷斯第四版p235&#xff09;&#xff1a; 代码&#xff1a; 结果&#xff1a; 原理&#xff08;冈萨雷斯第四版p235&#xff09;&#xff1a; 代码&#xff1a; import cv2 import numpy as np from matplotlib import pyplot as plt# for gray im…

自编自适应中值滤波器

自适应中值滤波器 算法思想&#xff1a;自适应中值滤波器是根据输入的图片像素矩阵和滤波器窗口的最大和最小值&#xff0c;首先&#xff0c;根据滤波器窗口的最大值申请两个可以处理了边界情况的滤波器&#xff0c;大小为原图加上最大滤波器的尺寸减一&#xff0c;按照边缘处…

图像中值滤波器python实现

中值滤波器原理 图像处理中最著名的统计排序滤波器是中值滤波器&#xff0c;即用一个预定义的像素领域中的灰度中值来代替像素的值&#xff1a; 其中是以&#xff08;x,y&#xff09;为中心的领域&#xff0c;包含中心点自己&#xff0c;在领域中找到中值&#xff0c;并用中值…

中值滤波器 median filter

中值滤波 中值滤波器(median filter)是将每个像素替换为围绕这个像素的矩形领域内的中值&#xff0c;或”中值像素"。 通过平均的简单模糊对噪声图像&#xff0c;由其是有较大孤立的异常值非常敏感。少量具有较大偏差的点也会严重影响到均值滤波。中值滤波可以采用取中间…

中值滤波器

我们前面提到&#xff0c;使用平均操作或加权平均操作可以降低图像的噪声&#xff0c;并由此引出了空间滤波器的概念。 这种平均操作或加权平均操作的空间滤波器&#xff0c;根据平均操作的特点&#xff0c;可以叫做均值滤波器。均值&#xff0c;就是平均值得意思。我们在《统…

C Primer Plus 第1章 初识C语言 笔记

C语言的起源 1972年&#xff0c;贝尔实验室的丹尼斯里奇&#xff08;Dennis Ritch&#xff09;和肯汤普逊&#xff08;Ken Thompson&#xff09;在开发UNIX操作系统时设计了C语言。 选择C语言的理由 用C语言编写的程序更易懂、更可靠。C语言充分利用了当前计算机的优势&…

C语言 基于结构体的程序设计(PTA)

一、实验目的 1&#xff0e;掌握C语言中结构体类型的定义和结构体变量的定义和引用。 2&#xff0e;掌握用结构指针传递结构数据的方法。 二、实验内容 1、 计算职工工资 给定N个职员的信息&#xff0c;包括姓名、基本工资、浮动工资和支出&#xff0c;要求编写程序顺序输…

C语言学习笔记(kk-zkx)

前言 流行的编程语言编程语言的大致发展历程编程语言应用数据在内存中的储存程序载入内存ASCII编码GB2312和GBKUnicode字符集&#xff08;统一码&#xff0c;万国码&#xff09;就业坑&#xff0c;当心 编程语言&#xff1a;用来控制计算机&#xff0c;让计算机为我们做事情的语…

C语言简介--学前必备知识

关键字 32个关键字&#xff1a; C和C的关系 C 主要在C语言的基础上增加了面向对象和泛型的机制&#xff0c;提高了开发效率&#xff0c;以适用于大中型软件的编写。C支持面向过程编程、面向对象编程和泛型编程&#xff0c;而C语言仅支持面向过程编程。就面向过程编程而言&a…

C语言入门篇——文件操作篇

目录 1、为什么使用文件 2、什么是文件 2.1程序文件 2.2数据文件 2.3文件名 3、文件的打开和关闭 3.1文件指针 3.2文件的打开和关闭 4、文件的顺序读写 5、文件的随机读写 5.1fseek 5.2ftell 5.3rewind 6、文本文件和二进制文件 7、文件读取结束的判定 8、文件…

C语言基础之13:文件输入/输出

Tips1&#xff1a; 函数&#xff1a;fopen()、getc()、putc()、exit()、fclose() fprintf()、fscanf()、fgets()、fputs() rewind()、fseek()、ftell()、fflush() fgetpos()、fsetpos()、feof()、ferror() ungetc()、setvbuf()、fread()、fwrite() 如何使用C标准I/O系列的函数…

01是c语言,01-C语言-简介

一、C语言的起源 1972年&#xff0c;由贝尔实验室的丹尼斯.里奇和肯.汤普逊在开发UNIX系时设计C语言。C语言是在B语言基础上进行设计的。C 语言设计的初衷是将其作为程序员使用的 一种编程工具&#xff0c;因此&#xff0c;其主要目标是成为有用的语言。 二、C语言的特性 设计特…

用C语言实现CLI界面的魔塔游戏

简介 本着开源的精神&#xff0c;我分享下我做的数据结构大作业&#xff0c;我当时选择的是游戏设计题目&#xff0c;由于魔塔基础的机制不太复杂&#xff0c;所以就借着大作业设计了个简易的魔塔游戏。 这是游戏界面&#xff1a; 以下是我当时大作业内容&#xff1a; 我把…

C语言入门(什么是C语言,C语言的编程机制以及一些基础计算机概念)

目录 一.什么是C语言 1.面向对象&#xff1a; 2.面向过程&#xff1a; 二.C语言特点 三.C语言开发时间 四.环境搭建 1.代码编辑器 2.C编译器 五.C语言标准 六.计算机补充知识 1.计算机构成 2.CPU工作 3.编译器 七.编写程序步骤 八.源文件&#xff0c;目标文件&a…

C语言 09.文件

读写文件与printf、scanf关联 printf – 屏幕 – 标准输出 scanf – 键盘 – 标准输入 perror – 屏幕 – 标准错误 系统文件&#xff1a;&#xff08;打开和关闭由系统自动执行&#xff09; 标准输入 – stdin – 0 一旦关闭了&#xff0c;scanf就不可以使用 标准输出 – s…

C语言完整知识体系总结

C语言的知识体系总结 这里写目录标题 C语言的知识体系总结序言&#xff1a;C语言的概述历史、特点、标准&#xff09;1、嵌入式开发为什么选择C语言&#xff1f;&#xff08;面试题&#xff01;&#xff09;2、为什么内核开发选择C语言&#xff1f;3、C语言的缺点&#xff1a;a…

【C语言篇】初识C语言

友情链接&#xff1a;C/C系列系统学习目录 知识总结顺序参考C Primer Plus&#xff08;第六版&#xff09;和谭浩强老师的C程序设计&#xff08;第五版&#xff09;等&#xff0c;内容以书中为标准&#xff0c;同时参考其它各类书籍以及优质文章&#xff0c;以至减少知识点上的…