机器视觉作业|8邻接外边界追踪4.23
-
作业要求:使用8-邻接实现外边界跟踪或者扩展边界跟踪(此处还是选用外边界跟踪)
-
二值图像中测试程序,保证其对单个像素物体和单像素宽度物体有效。
-
输入:
二值图像
-
输出:
测试图像的边界图像
-
说明对于单像素和单像素宽度物体的处理方法,给出各种二值图像的处理结果。
clear all;
close all;
clc;
A=imread('rice.png');
img = im2bw(A,0.5); %首先对图像二值化
%figure(1)
subplot(131);imshow(A) %显示原始的图片
[m, n]=size(img); %获取图像大小,目的是对图像的边界进行处理
for x=1:m %把最外层去掉,否则当dir到边界是会出错
for y=1:n
if x==1||x==m||y==1||y==n
img(x,y)=0;
end
end
end
%figure(2)
subplot(132);imshow(img) %显示二值化之后的图片
img1=zeros(m,n); %内边界标记图像
img2=zeros(m,n); %外边界标记图像
img3=zeros(m,n); %检索次数标记图像,目的是避免出现死循环
ed=[0 1;-1 1;-1 0;-1 -1;0 -1;1 -1;1 0;1 1]; %八邻接跟踪的0方位开始逆时针搜索
for i=2:m-1 %二重循环遍历整个图像
for j=2:n-1
if img(i,j)==1 && img1(i,j)==0 %当前是没有内边界标记的白色像素
add=img(i,j-1)+img(i+1,j)+img(i,j+1)+img(i-1,j);
if sum(sum(img(i-1:i+1,j-1:j+1)))~=9 &&add~=4 %块内部的白像素不进行标记
i1=i; %在像素块内部搜寻内边界时使用的坐标
j1=j;
img1(i,j)=1; %本像素块内第一个标记的边界,使其内边界标记置为1
img3(i,j)=1; %检索次数标记为1
condition=true; %循环条件
i2=0;
j2=0; %(i2,j2)表示第二个被检索到的像素坐标
in=0; %(in,jn)为当前位置的前一个被检索的像素坐标
jn=0;
dir=7; %初始dir
num=1; %计数,方便找到(i2,j2)
while condition
if img3(i1,j1)==3 %防止出现死循环
condition=false;
end %dir算法找边界
if (mod(dir,2)==1) %奇数
dir=mod((dir+6),8);
else %偶数
dir=mod((dir+7),8);
end
for k=0:7 %逆时针八邻域搜索
tmpdir=mod((dir+k),8); %更改八邻接跟踪的dir方位
tmpi=i1+ed(tmpdir+1,1); %八邻域临时坐标
tmpj=j1+ed(tmpdir+1,2);
if img(tmpi,tmpj)==1 %搜索到白色边界
num=num+1;
i1=tmpi; %更新内部搜寻坐标,继续搜索
j1=tmpj;
dir=tmpdir;
img1(i1,j1)=1; %该像素标记为内边界
img3(i1,j1)=img3(i1,j1)+1; %所有检索过的白色像素用img3进行计数
if num==2
i2=tmpi; %第二个被检索到的内边界像素
j2=tmpj;
end
in=tmpi-ed(dir+1,1); %前一个被检索的内边界像素
jn=tmpj-ed(dir+1,2);
break;
else %没有搜索到白色边界时
if k==7
img2(tmpi,tmpj)=1; %该像素标记为外边界
condition=false;
else
img2(tmpi,tmpj)=1; %该像素标记为外边界
end
end
end
if (i1==i2)&&(j1==j2)&&(in==i)&&(jn==j)&&num~=2 %当前等于第二个,倒数第二个等于第一个
condition=false;%终止循环条件
end
end
end
end
end
end
for i=2:m-1 %单像素边界情况下单独循环讨论
for j=2:n-1
if img1(i,j)==1 %只有当当前像素是内边界时执行
for k=1:8
i1=i+ed(k,1);
j1=j+ed(k,2);
if img(i1,j1)==0 && img2(i1,j1)~=1 %周围的像素如果不是白色像素也不是外边界时标记为外边界
img2(i1,j1)=1;
end
end
end
end
end
%figure(3);
subplot(133);imshow(img2,[]);