中值滤波器

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

中值滤波器.txt让人想念而死,是谋杀的至高境界,就连法医也鉴定不出死因。。。。。。帽泡排序法的汇编实现。。
mov cx,count ;CX←数组元素个数
dec cx ;元素个数减1为外循环次数
outlp:

mov dx,cx ;DX←内循环次数
mov bx,offset array
inlp: mov al,[bx] ; 取前一个元素
cmp al,[bx+1] ;与后一个元素比较
jna next
xchg al,[bx+1] ;否则,进行交换
mov [bx],al
next: inc bx ;下一对元素
dec dx
jnz inlp ;内循环尾
loop outlp ;外循环尾



2、中值滤波
中值滤汉是对某一参数连续输入N次(一般N取奇数),从中选择一个中间值作为本次采样值,若变量变化比较缓慢,采用此方法效果比较好,但对快速变化过程的参数,如流量、自然伽玛等,则不宜采用。
中值滤波的C程序函数如下:
float middle_filter(float middle_value [] , intcount)
{
float sample_value, data;
int i, j;
for (i=1; i for(j=count-1; j>=i,--j){
if(middle_value[j-1]=middle_value[j]{
data=middle_value[j-1];
middle_value[j-1]=middle_value[j]
middle_value[j]=data;
}
}
sample_value=middle_value(count-1)/2];
return(sample_value);
}
函数假设对某一参数连续采样3次,若多次采样,可 对该函数稍作修改即可。3次采样值存储在数组middle_value[3],其中Sample-value表示有效采样值,count表示连续采样次数。




FILTER3:
MOV R2,#04H
SRT:
MOV A,R2
MOV R3,A
MOV R0,#SAMP
LOOP:
MOV A,@R0
INC R0
MOV R1,A
CLR C
SUBB A,@R0
MOV A,R1
JC DONE
MOV A,@R0
DEC R0
XCH A,@R0
INC R0
MOV @R0,A
DONE:
DJNZ R3,LOOP
DJNZ R2.,SORT
INC R0
MOV A,@R0
RET
SAMP EQU 30H


用汇编实现冒泡排序的函数
;参数说明:_lpData是待排序的数组首地址,_dwCount是待排序的个数,_dwOption设为0则由小到大排序
;如果是非0值,则是由大到小排序.
;返回值:已排序数据放回原数组中.
;作者:ONEPROBLEM
;=================================================
_BubblingSort proc _lpData,_dwCount,_dwOption
local @dwCount

pushad
mov edi,1
.while edi < _dwCount
mov esi,_lpData
mov eax,_dwCount
mov @dwCount,eax
sub @dwCount,edi
mov ebx,1
.while ebx <= @dwCount
mov eax,[esi]
.if eax<[esi+4] && _dwOption==0
jmp next
.elseif eax>[esi+4] && _dwOption==0
jmp continue
.elseif eax<[esi+4] && _dwOption!=0
jmp continue
.elseif eax>[esi+4] && _dwOption!=0
jmp next
.endif
continue:
mov eax,[esi]
mov edx,[esi+4]
mov [esi],edx
mov

[esi+4],eax
next:
add esi,4
inc ebx
.endw
inc edi
.endw
popad
ret
_BubblingSort endp







DSEG SEGMENT
n equ 10
BUFFER DB 9,11,2,7,21,13,2,0,14,3
DSEG ENDS
CSEG SEGMENT
assume cs:CSEG, ds:DSEG
MAIN PROC FAR ;主程序入口
mov ax, dseg
mov ds, ax
mov cx,n
dec cx
loop1: mov di,cx
mov bx,0
loop2: mov al,buffer[bx]
cmp al,buffer[bx+1]
jge continue
xchg al,buffer[bx+1]
mov buffer[bx],al
continue: add bx,1
loop loop2
mov cx,di
loop loop1
mov ah,1;按任意键退出
int 21h
mov ax, 4c00h ;程序结束,返回到操作系统系统
int 21h
MAIN ENDP
CSEG ENDS
END MAIN



中值滤波原理
中值滤波是一种非线性平滑法,它对一个滑动窗口内的像素灰度值排序,并用其中值代替窗口中心像素的灰度值. 对脉冲干扰及椒盐噪声具有良好的抑制作用,并且在抑制随机噪声的同时能有效保护边缘少受模糊. 二维中值滤波的窗口形状有多种,如线状、方形、十字形、圆形、菱形等. 不同形状的窗口产生不同的滤波效果. 通过研究,不少文献认为十字中值滤波的效果优于方形的中值滤波,而且十字中值滤波也有不同的形式以形成不同的滤波特性,其数据可从方形数据获得. 最常使用的十字中值滤波是对五个相邻像素进行排序,以确定中心点的数值.


I=[1 7 1 8 1 7 1 1
1 1 1 5 1 1 1 1
1 1 5 5 5 1 1 7
1 1 5 5 5 1 8 1
8 1 1 5 1 1 1 1
8 1 1 5 1 1 5 1
1 1 1 5 1 1 1 1
1 7 1 8 1 7 1 1
];
[M N]=size(I);
I1=zeros(M,N);
for i=2:M-1
for j=2:N-1
temp=I(i-1:i+1,j-1:j+1);
temp=sort(temp);
temp=sort(temp');
I1(i,j)=temp(2,2);
end
end
imshow(I,[]);
figure,imshow(I1,[]);


中值滤波器属于非线性空间滤波器,用于除去图像中的椒盐噪声。中值滤波器只适用于灰度RGB图像(对于YUV图像,应该只需要对Y进行处理),一个有趣现象:对于彩色RGB图像进行中值滤波,得到的输出接近于灰色图像。中值滤波的算法核心就是找出中间值。对于一个3x3的块,只需要找的这样一个值:1)有4个比它小;2)有4个比它大。而不需要进行泡沫排序。对于图像的边界,一般有两种处理方法:边界扩展和不处理。为了跟具有普遍性,此IP不考虑边界问题。

中值滤波器的主要开销在于line buffer,通常line buffer需要存储图像的一行像素。对于3x3块的滤波,就需要两个line buffer,这对于大尺寸图像是一笔很大的开销。我认为,对于这个问题有两种解决办法:1)和其它模块共享buffer,实际限制会比较多,也会影响系统的工作频率;2)把大图像分成小块来处理,这样做IO接口的设计会比较复杂,对于带宽也有一定

影响。

本文的IP为Slave模式,输入为8bit,支持断续传输。实际应用中,需要设计一个IO interface。使用了6级流水线,处理速度可以达到1pixel/cycle。

作为一个IP,这个设计可能没有太多价值,毕竟实际情况千差万别。但是,我想,作为一个学习的例子还是有一些意义的,这个设计流程已经很接近工程项目了。算法实现起来比较简单,总共花费约5个工作日。

第一天:找资料;

第二天:写Design Spec,并实现;

第三天:写c model,建立仿真环境;

第四天:debug;

第五天:整理。

整个工程包括:RTL,testbanch,c model,Design Spec和测试向量。要求仿真工具支持verilog 2001。这里对验证环境多说一些,严格来讲,这个只能算是仿真,验证的话需要给出function coverage和code coverage报告。因为是没有薪水的工作,所以就不愿意做这些琐碎的事情了。凭我的直觉说应该不会有问题(千万不要对自己的老板这么说,而且bug往往出现在设计者认为不会出bug的地方)。找Bug的工作就交给大家了:)。对于仿真结果的比较,不知道为什么很多人都习惯用testbanch dump result file,然后和参考数据作比较。个人觉得这种方法非常不好,我习惯用monitor做实时比较。到了2001版本,verilog的文件操作已经做到和c一样强大了。在这个testbanch里,激励和比对文件都是二机制的。

另外一个比较重要的东西就是c model了,一般在公司里都是由算法工程师给出来的(我请不起他们只有自己写了),个人认为c model不会对RTL的实现有所帮助(我从来不看他们的程序,而且我的设计都是和c model同步完成的),但是对于debug起着事半功倍的作用。一个好的c model可以给出debug所需要的所有信息。

关于滤波器的实现没有太多难点,这里用的是脉动阵列结构,保证数据在你期望的时间到达就可以了。有一些信号是根据时序凑出来的,不要深究其逻辑意义。基本上基于算法的设计都遵循以下流程:先实现数据通路,然后根据数据通路来凑出控制信号.

通常我看code和波形都是在debussy下面,如果你不是,应该向我学习,因为aisc工程师都是这么做的!如果你是想学习而不是拿来用的话,我建议还是自己实现的好。





网络上的资源:

该文件内容放在.m 文件中才能调用!!!

%中值滤波函数,X为输入矩阵,a,b为中值滤波的框大小。

%效率很低,可以用来说明中值滤波的概念。

%Y为uint8数据类型,以便用imshow画图,否则,可以改为其它和X相同的类型。

% medianforfun.m

function [Y]=medianforfun(X,a,b)

k=floor(a*b/2)+1; % k为矩阵数值中间位置的数

[M,N]=size(X);

uint8 Y=zeros(M,N);

funBox=zeros(a,b);


temp=zeros(a*b);

for i=1:M-a % matlab的坐标从(1,1)开始

for j=1:N-b

funBox=X(i:i+a,j:j+b);

temp=funBox(:); % A(:)矩阵A以一维数组的形式输出

tempSort=sort(temp); % sort()是从小到大排列

Y(i,j)=tempSort(k);

end;

end;


调用函数:

I = imread('eight.tif');

J = imnoise(I,'salt %26amp; pepper',0.02);

K = medfilt2(J);

imshow(J), figure, imshow(K)

Z=medianforfun(J,2,2);

figure, imshow(Z)


2.

原版修改(效果更好):

function [Y]= V0(X,a,b)

k=floor(a*b/2)+1; % k为矩阵数值中间位置的数

[M,N]=size(X);

uint8 Y=zeros(M,N);

funBox=zeros(a,b);

p=0;

temp=zeros(a*b); % a*b 的方阵

for i=1:M-a % matlab的坐标从(1,1)开始

for j=1:N-b

funBox=X(i:i+a-1,j:j+b-1);

temp=funBox(:); % A(:)矩阵A以一维数组的形式输出

tempSort=sort(temp); % sort()是从小到大排列

p1=i+floor(a/2)+1;

p2=j+floor(a/2)+1;

Y(p1,p2)=tempSort(k); %找到邻接矩阵排列数的中值赋值给模板的中心点

end;

end;


调用函数:

tic;

In = imread('D:\sp.jpg'); % 用P= isind('D:\sp.png')测试,发现此图片为索引图像

I= rgb2gray(In); %那为何使用rgb2gray能转换,ind2gray却不能呢???

imhist(I);

J = imnoise(I,'salt %26amp; pepper',0.08);

% K = medfilt2(J);

imshow(J);

%figure,imshow(K)

Z= V0(J,3,3); %模板为3*3的矩阵,矩阵越大,计算量越大

figure, imshow(Z)

toc


说明:

计算程序运行时间的方式:

tic;

程序;

toc

(2)
matlab自带的中值滤波函数:medfilt2( )


判断图像文件的类型:

In = imread('D:\sp.png');

P= isind('D:\sp.png')

P= isrgb('D:\sp.png')

效果如下:



图片处理前 图片处理后


3.

改进版(在原版修改基础上):

传统的中值滤波中“中值”一般取“中位数”,即所有元素排序后中间位置上的元素值。但是排序需要移动大量元素,效率较低。


个人认为,其实原版算法主要耗时的地方之一是matlab的排序函数:sort()

说明:耗时的原因很多!值得改进的地方还有很多~~


基于此点,可以改进排序函数,快速排序算法是我的首选,但是不是平常意义的那种快速排序,是经过改良的快速排序。


因为它每轮移动的数字都是最后排好序的最终位置,并且,我只是为了找中值,所以不需要真的去排序。只要在有一轮排序中,一个数字被放在中心位置,那么该数就是所要找的中值。最终的排序虽然没有完成,但中值已找到,所以循环就可以停止了!!但仍需要移动元素位置。


貌似还是很耗时!!!!暂时我只能改进到这样的情况了,尽力了~!


1.快速排序法(matlab版)

% 快速排序法

% 基本的思想:通过一趟排序将待排的记录分割成独立的两部分,

% 其中前

一部分的 记录的关键字均比另一部分记录的关键字小,

% 再分别对两组记录进行递归分割,达到排序的目的

% 平均时间复杂度为 O(log2(n))

function [data]=qsort_main(A)

data = A; low = 1; high = 9;

data = QSort(data, low, high);

%before=A(:)

%after=data(:)



function data = QSort(data, low, high)

if nargin == 1

low = 1;

high = length(data);

end

if(low%26lt;high)

[data pivokey] = qPartition(data, low, high);



(3)
if(pivokey==5) %特定情况处理,如果第一个数就是中值,那么就可以停止该循环了!

return;

end

data = QSort( data, low, pivokey - 1 );%递归调用

data = QSort( data, pivokey + 1, high );

end


% 将数组分成两部分,前一部分的值均比后一部分值小

% 返回分界点



function [data low] = qPartition(data, low, high)

if nargin == 1

low = 1;

hight = length(data);

end

pivokey=data(low);

while low %26lt; high

while low %26lt; high %26amp; data(high) %26gt;= pivokey

high = high - 1;

end

c = data(low); d = data(high);

data(low) = d; data(high) = c;

while low %26lt; high %26amp; data(low) %26lt;= pivokey

low = low + 1;

end

c = data(low); d = data(high);

data(low) = d; data(high) = c;

if(low==high%26amp;low==5) %low与high均到达中心位置!!!!!

% fprintf('ppppppppp');

return;

end

end


中值滤波函数:

function [Y]= V0(X,a,b)

k=floor(a*b/2)+1; % k为矩阵数值中间位置的数

[M,N]=size(X);

uint8 Y=zeros(M,N);

funBox=zeros(a,b);

temp=zeros(a*b); % a*b 的方阵

for i=1:M-a % matlab的坐标从(1,1)开始

for j=1:N-b

funBox=X(i:i+a-1,j:j+b-1);

temp=funBox(:); % A(:)矩阵A以一维数组的形式输出

tempSort=qsort_main(temp); % 快速排序!!!!!

p1=i+floor(a/2)+1;

p2=j+floor(a/2)+1;

Y(p1,p2)=tempSort(k); %找到邻接矩阵排列数的中值赋值给模板的中心点

end;

end;



调用函数:

tic;

In = imread('D:\sp.jpg'); % 用P= isind('D:\sp.png')测试,发现此图片为索引图像

I= rgb2gray(In); %那为何使用rgb2gray能转换,ind2gray却不能呢???

imhist(I);

J = imnoise(I,'salt %26amp; pepper',0.08);

% K = medfilt2(J);

imshow(J);

%figure,imshow(K)

Z= V0(J,3,3); %模板为3*3的矩阵,矩阵越大,计算量越大

figure, imshow(Z)

toc

相关文档
最新文档