关于位图边缘的检测定位

来源:互联网 发布:电气常用数据手册 编辑:程序博客网 时间:2024/05/22 18:20

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

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


POTDR_室外实验_20140120_160549TwoPoint2.mat

此文件为原始数据文件。我们需要将其转化为位图

进行分析处理。


部分matlab程序:

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



显示差分灰度图:
imshow(DiffData),title('差分灰度图');

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

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


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

膨胀matlab代码:

B=[ 0 1 0      1 1 1     0 1 0      ];   A1=imdilate(I,B);%图像I被结构元素B膨胀  A2=imdilate(A1,B);  A3=imdilate(A2,B);  A4=imdilate(A3,B);  A5=imdilate(A4,B);  A6=imdilate(A5,B);  A7=imdilate(A6,B);  A8=imdilate(A7,B);  A9=imdilate(A8,B);  A10=imdilate(A9,B);  A11=imdilate(A10,B);       A12=imdilate(A11,B);  A13=imdilate(A12,B);  A14=imdilate(A13,B);  A15=imdilate(A14,B);       A16=imdilate(A15,B);  A17=imdilate(A16,B);  A18=imdilate(A17,B);  A19=imdilate(A18,B);       A20=imdilate(A19,B);  A21=imdilate(A20,B);  A22=imdilate(A21,B);  A23=imdilate(A22,B);       A24=imdilate(A23,B);  A25=imdilate(A24,B);  A26=imdilate(A25,B);  A27=imdilate(A26,B);       A28=imdilate(A27,B);  A29=imdilate(A28,B);

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

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


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

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


轮廓逐渐清晰明了。


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

其实这里的原理很简单。


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

比如p5=[17 17 17 17 17 17 1718 18 18 18 18 18 19 19 19 19 19 19 19 20 20 21 21....... 22 22 23 23 24 24 25 25 25 25 25 25 26 26 26]

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



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

看图如下:

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

matlab代码如下:

  p=sparse(LastPerim);%对LastPerim求稀疏矩阵即只保留值为1的元素    p1=find(p);  %按列索引,即找出稀疏矩阵的按列一维索引    p2=p1/388  %388为列数,此值为稀疏矩阵中保留位置的列值    p3=floor(p2)   %对p2进行取整    p4=p3'   %转置成一维行向量   len=length(p4)-1;  len=len-388; %减去最后一列边缘的388个数据点  calculate=0;  k=1;    p5=p4(:,1:len);%%找出p4中连续五个以上相等的数存储在memlocate中  for i=1:1:len-4      if (p5(i)==p5(i+1)&&p5(i+1)==p5(i+2)&&p5(i+2)==p5(i+3))          calculate=calculate+1;      else          if(calculate>=3)                  memlocate(k) = p5(i);                  k=k+1;                  calculate=0;            end      end  end


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



4.而此时我们只需要在memlocate中进行分类即可.

我们在这里用简单相邻列的差来区分x1和x3这两个不同的边缘.

如何差值等于1则表明是属于同一类。否则属于不同类。

这样便把不同类的列位置得到了,定位也随即完成.


此部分matlab代码如下:

%%对入侵点进行定位p=1;j=0;for t=1:1:k-2    j=j+1;    if((memlocate(t+1)-memlocate(t))>=2)         fid=fopen('LocateResult15.txt','at+');         fprintf(fid,'The %d location is:%d\n',p,memlocate(t+1-j));         p=p+1;         j=0;    endend

LocateResult.txt截图如下:



第一边缘列的位置在17列,第二边缘列的位置在254列.


定位成功!




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


作者水平有限.至于VC实现部分后续有时间再完善。如果文中有纰漏或者不足之处,还望读


者匹配指正。



转载请注明作者:小刘


1 0
原创粉丝点击