基于 PCNN 的图像分割的 matlab 实现
图像分割是一种重要的图像技术,在理论研究和实际应用中都得到了人们的广泛重视。图像分割的方法和种类有
很多,有些分割运算可直接应用于任何图像,而另一些只能适用于特殊类别的图像。有些算法需要先对图像进行
粗分割,因为他们需要从图像中提取出来的信息。例如,可以对图像的灰度级设置门限的方法分割。许多不同种
类的图像或景物都可作为待分割的图像数据,不同类型的图像,已经有相对应的分割方法对其分割,同时,某些
分割方法也只是适合于某些特殊类型的图像分割。分割结果的好坏需要根据具体的场合及要求衡量。图像分割是
从图像处理到图像分析的关键步骤,可以说,图像分割结果的好坏直接影响对图像的理解。
脉冲耦合神经网络( PCNN) 是一种不同于传统人工神经网络的新型神经网络,它有着重要的生物学背景,是由E
ckhorn 为解释在猫的大脑视觉皮层中实验所观察到的与特征有关的神经元同步行为现象而提出的。PCNN 的
这个生物学背景使它在图像处理中具有先天优势,有着与传统方法进行图像处理所无法比拟的优越性。下面的程
序是基于PCNN 最基本的图像分割的matlab 实现,分割效果较好。
主程序:
1.
2.
3.
4.
function[Edge,Numberofaera]=PCNN(X)
%X:输入的灰度图像,Edge:检测到的一些边界点,Numberofaera 则表明了在各次迭代时激活的块区域
clear;
clc;
5.
6.
7.
8.
9.
I=imread('lena1.bmp');
[Xa,Ya]=size(I);
subplot(1,2,1);
imshow(I);
%imshow(I);
10.
X=double(I);
11.
%X=double(imread('lena.bmp'));
12.
Weight=[0.5 1 0.5;1 0 1;0.5 1 0.5];
%此可权值矩阵的选取原则(或者根据)是什么?
13.
Beta=0.32;
14.
Yuzhi=200;
15.
Decay=0.31;
16.
[a,b]=size(X);
17.
Threshold=zeros(a,b);
18.
S=zeros(a+2,b+2);
19.
B=zeros(a,b);
%标记样板,表明该pixel 是否被激活过;
20.
Y=zeros(a,b);
21.
Edge=zeros(a,b);Numberofaera=zeros(a,b);Numberofaera_1=zeros(a,b);
22.
Num_1=0;Num=0;
23.
n=1;
24.
while(sum(sum(B))~=Xa*Ya)
%若采用128*128 的图像,须注意。
25.
for i0=2:a+1
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
for i1=2:b+1
V=[S(i0-1,i1-1) S(i0-1,i1) S(i0-1,i1+1);
S(i0,i1-1) S(i0,i1) S(i0,i1+1);
S(i0+1,i1-1) S(i0+1,i1) S(i0+1,i1+1)];
L=sum(sum(V.*Weight));
F=X(i0-1,i1-1);
U=double(F)*(1+Beta*double(L));
if U>=Threshold(i0-1,i1-1)|Threshold(i0-1,i1-1)<95
T(i0-1,i1-1)=1;
%这是什么?
Threshold(i0-1,i1-1)=Yuzhi;
Y(i0-1,i1-1)=1;
if n==1
B(i0-1,i1-1)=0;
%避免第一次全部激发造成的影响
else
B(i0-1,i1-1)=1; %已发射过的标记
Threshold(i0-1,i1-1)=1000000;%相当于不会被第二次激活
end
else
T(i0-1,i1-1)=0; %no use?
Y(i0-1,i1-1)=0;
end
47.
48.
end
end
49.
Threshold(find(B~=1))=exp(-Decay)*Threshold(find(B~=1));
50.
%被激活过的像不再参与迭代过程
51.
if n~=1
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
Edge=Edge+judge_edge(Y,n);
Y(find(Edge<0))=0;
%边界点被置零,Y 本来是激发的像素,现在边界被置零,
%也不能说白激发了,B 矩阵有纪录!当然下次就休想再被激发
[Numberofaera_1,Num_1]=bwlabel(Y,4);
for i=1:a
for j=1:b
if Numberofaera_1(i,j)~=0
Numberofaera_1(i,j)=Numberofaera_1(i,j)+Num;
end
end
end
Numberofaera=Numberofaera+Numberofaera_1;
Num=Num_1;
65.
end
66.
if n==1
67.
S=zeros(a+2,b+2);
68.
else
69.
S=Bianhuan(T);
70.
end
71.
n=n+1;
72.
Numberofaera_1=zeros(a,b);
73.
subplot(1,2,2);
74.
imshow(S);
75.
end %while
76.
77.
边缘检测:
1.
2.
3.
4.
5.
6.
7.
function Y=judge_edge(X,n)
%X:每次迭代后PCNN 输出的二值图像,如何准确判断边界点是关键
[a,b]=size(X);
T=Jiabian(X);
Y=zeros(a,b);
W=zeros(a,b);
for i=2:a+1
for j=2:b+1
8.
9.
10.
11.
if(T(i,j)==1)&((T(i-1,j)==0&T(i+1,j)==0)|(T(i,j-1)==0&T(i,j+1)==0)|(T(i
-1,j-1)==0&T(i+1,j+1)==0)|(T(i+1,j-1)==0&T(i-1,j+1)==0))
Y(i-1,j-1)=-n;
end
end
12.
end
这一步也非常重要——加边,所谓加班就是在二维方向上对图像进行扩充,把扩充后的图像最边缘作为图像的
边缘,以下程序实现图像的扩充
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
function Y=Jiabian(X)
[m,n]=size(X);
Y=zeros(m+2,n+2);
for i=1:m+2
for j=1:n+2
if i==1&j~=1&j~=n+2
Y(i,j)=X(1,j-1);
elseif j==1&i~=1&i~=m+2
Y(i,j)=X(i-1,1);
elseif i~=1&j==n+2&i~=m+2
Y(i,j)=X(i-1,n);
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
elseif i==m+2&j~=1&j~=n+2
Y(i,j)=X(m,j-1);
elseif i==1&j==1
Y(i,j)=X(i,j);
elseif i==1&&j==n+2
Y(i,j)=X(1,n);
elseif i==(m+2)&j==1
Y(i,j)=X(m,1);
elseif i==m+2&j==n+2
Y(i,j)=X(m,n);
else
Y(i,j)=X(i-1,j-1);
end
end
26.
end
27.
28.
变换:
1.
function Y=Bianhuan(X)
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
[m,n]=size(X);
Y=zeros(m+2,n+2);
for i=1:m+2
for j=1:n+2
if i==1|j==1|i==m+2|j==n+2
Y(i,j)=0;
else
Y(i,j)=X(i-1,j-1);
end
end
12.
end
变换和扩充几乎在每一个图像处理程序中都会用到,扩充也叫加边,另外还有去边的步骤。
处理效果: