关于位图边缘的检测定位

最近几天做了一些图像检测定位的工作,虽然老师否定了这一方法。但是还是想把最近的工作

总结总结。也许会对以后有所帮助。


POTDR_室外实验_20140120_160549TwoPoint2.mat此文件为原始数据文件。我们需要将其转

化为位图进行分析处理。


部分matlab程序:

 1 load POTDR_室外实验_20140120_160549TwoPoint2.mat  %加载数据
 2 
 3 Data=data(1:size(data,1),:);  %Data两点扰动的矩阵数据388行*3472列
 4 
 5 ColmStart=100;  %因数据量太大,需要对列数据进行采样。从第100列开始取数据 
 6 
 7 ColmLag=10;     %采样数据间隔,每隔10列采一列
 8 
 9 VAR=[];     %定义一个空向量
10     
11 ColmI=ColmStart:ColmLag:size(Data,2)-mod(size(Data,1),ColmLag)-ColmLag;   %ColmI为具体对3472列中哪些列进行采样绘图为1*331的向量
12 
13 NewData=Data(:,ColmI);  %NewData为在原3472行数据中采样抽取出来的145列.388*331(原始采样图像数据)
14   
15 DiffData=diff(NewData,1); %DiffData为对NewData作一阶差分运算的差分矩阵也是145列 388*331

 



显示差分灰度图:

1 imshow(DiffData),title('差分灰度图');

 

差分灰度图的边缘:(定位出红线的位置是本文的目标)

1 I=edge(DiffData,'sobel','vertical');%差分灰度图的边缘
2 imshow(I),title('差分灰度的边缘');

 


由于红色边缘并不突出,所以我们需要利用图像膨胀使边缘轮廓清晰.膨胀matlab代码:

 1 B=[ 0 1 0  
 2     1 1 1 
 3     0 1 0 
 4      ];
 5  
 6   A1=imdilate(I,B);%图像I被结构元素B膨胀
 7   A2=imdilate(A1,B);
 8   A3=imdilate(A2,B);
 9   A4=imdilate(A3,B);
10   A5=imdilate(A4,B);
11   A6=imdilate(A5,B);
12   A7=imdilate(A6,B);
13   A8=imdilate(A7,B);
14   A9=imdilate(A8,B);
15   A10=imdilate(A9,B);
16   A11=imdilate(A10,B);
17      
18   A12=imdilate(A11,B);
19   A13=imdilate(A12,B);
20   A14=imdilate(A13,B);
21   A15=imdilate(A14,B);
22      
23   A16=imdilate(A15,B);
24   A17=imdilate(A16,B);
25   A18=imdilate(A17,B);
26   A19=imdilate(A18,B);
27      
28   A20=imdilate(A19,B);
29   A21=imdilate(A20,B);
30   A22=imdilate(A21,B);
31   A23=imdilate(A22,B);
32      
33   A24=imdilate(A23,B);
34   A25=imdilate(A24,B);
35   A26=imdilate(A25,B);
36   A27=imdilate(A26,B);
37      
38   A28=imdilate(A27,B);
39   A29=imdilate(A28,B);

 


膨胀29次后的图像(红色边缘逐渐清晰):

1 imshow(A29);title('3*3第二十九次膨胀');

 


画出膨胀后的轮廓以便进行最终的红线定位:

1    LastPerim=bwperim(A29); %对膨胀29次的图像求轮廓
2    imshow(LastPerim),title('二十九次膨胀后的轮廓');

 

轮廓图如下:


轮廓逐渐清晰明了。


那么接下来我们如何检查出这两条红线的位置呢。

其实这里的原理很简单。


1.我们首先只保留图像中白线列信息。

比如p5=[17 17 17 17 17 17 17 18 18 18 18 18 18 19 19 19 19 19 19 19 20 20 21 21....... 22 22 23 2324 24 25

25 25 25 25 25 26 26 26]

表明第17列有7个点,第18列有6个点依次类推



2.我们还需要了解这样的一个原理.

看图如下:

3.显然根据上图我们不难将x1和x3附近所以的列保留下来.保存至memlocate向量中.

matlab代码如下:

 1  p=sparse(LastPerim);%对LastPerim求稀疏矩阵即只保留值为1的元素
 2   
 3   p1=find(p);  %按列索引,即找出稀疏矩阵的按列一维索引
 4   
 5   p2=p1/388  %388为列数,此值为稀疏矩阵中保留位置的列值
 6   
 7   p3=floor(p2)   %对p2进行取整
 8   
 9   p4=p3'   %转置成一维行向量
10  
11   len=length(p4)-1;
12   len=len-388; %减去最后一列边缘的388个数据点
13   calculate=0;
14   k=1;
15   
16   p5=p4(:,1:len);
17 %%找出p4中连续五个以上相等的数存储在memlocate中
18   for i=1:1:len-4
19       if (p5(i)==p5(i+1)&&p5(i+1)==p5(i+2)&&p5(i+2)==p5(i+3))
20           calculate=calculate+1;
21       else
22           if(calculate>=3)
23                   memlocate(k) = p5(i);
24                   k=k+1;
25                   calculate=0;  
26           end
27       end
28   end

 

memlocate截图如下:其中x1和x3附近总共只有21列保留了下来



4.而此时我们只需要在memlocate中进行分类即可.我们在这里用简单相邻列的差来区分x1和x3这两个不同的边缘.如何差值

等于1则表明是属于同一类。否则属于不同类。这样便把不同类的列位置得到了,定位也随即完成.


此部分matlab代码如下:

 1 %%对入侵点进行定位
 2 p=1;
 3 j=0;
 4 
 5 for t=1:1:k-2
 6     j=j+1;
 7     if((memlocate(t+1)-memlocate(t))>=2)
 8          fid=fopen('LocateResult15.txt','at+');
 9          fprintf(fid,'The %d location is:%d\n',p,memlocate(t+1-j));
10          p=p+1;
11          j=0;
12     end
13 end

 


LocateResult.txt截图如下:


第一边缘列的位置在17列,第二边缘列的位置在254列.定位成功!

 

我相信如果大家今后在工作中遇到类似的工作,那么一点能从这篇文章中获取一定的启发.

 


 

posted @ 2014-07-09 17:15  vpoet  阅读(336)  评论(0编辑  收藏  举报