最近几天做了一些图像检测定位的工作,虽然老师否定了这一方法。但是还是想把最近的工作
总结总结。也许会对以后有所帮助。
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 ',p,memlocate(t+1-j)); 10 p=p+1; 11 j=0; 12 end 13 end
LocateResult.txt截图如下:
第一边缘列的位置在17列,第二边缘列的位置在254列.定位成功!
我相信如果大家今后在工作中遇到类似的工作,那么一点能从这篇文章中获取一定的启发.