function [cout,marked_img,BW_edge]=corner(varargin)
% 输出 :
% cout - 检测图像的轮廓坐标.
% marked_image - 带有轮廓标记的图像.
%
%
[I,C,T_angle,sig,H,L,Endpoint,Gap_size] = parse_inputs(varargin{:});
if size(I,3)==3
I=rgb2gray(I); % 从彩色图转换为灰度图.
end
BW=edge(I,'canny',[L,H]); % 检测轮廓
[curve,curve_start,curve_end,curve_mode,curve_num,BW_edge]=extract_curve(BW,Gap_size); %提取曲线
cout=get_corner(curve,curve_start,curve_end,curve_mode,curve_num,BW,sig,Endpoint,C,T_angle); % 获取轮廓坐标
img=I;
for i=1:size(cout,1)
img=mark(img,cout(i,1),cout(i,2),5);
end
marked_img=img;
% figure(2)
% imshow(marked_img);
% title('轮廓检测')
% imwrite(marked_img,'corner.jpg');
function [curve,curve_start,curve_end,curve_mode,cur_num,BW_edge]=extract_curve(BW,Gap_size)
[L,W]=size(BW);
BW1=zeros(L+2*Gap_size,W+2*Gap_size);
BW_edge=zeros(L,W);
BW1(Gap_size+1:Gap_size+L,Gap_size+1:Gap_size+W)=BW;
[r,c]=find(BW1==1);
cur_num=0;
while size(r,1)>0
point=[r(1),c(1)];
cur=point;
BW1(point(1),point(2))=0;
[I,J]=find(BW1(point(1)-Gap_size:point(1)+Gap_size,point(2)-Gap_size:point(2)+Gap_size)==1);
while size(I,1)>0
dist=(I-Gap_size-1).^2+(J-Gap_size-1).^2;
[min_dist,index]=min(dist);
point=point+[I(index),J(index)]-Gap_size-1;
cur=[cur;point];
BW1(point(1),point(2))=0;
[I,J]=find(BW1(point(1)-Gap_size:point(1)+Gap_size,point(2)-Gap_size:point(2)+Gap_size)==1);
end
%向另一个方向提取轮廓
point=[r(1),c(1)];
BW1(point(1),point(2))=0;
[I,J]=find(BW1(point(1)-Gap_size:point(1)+Gap_size,point(2)-Gap_size:point(2)+Gap_size)==1);
while size(I,1)>0
dist=(I-Gap_size-1).^2+(J-Gap_size-1).^2;
[min_dist,index]=min(dist);
point=point+[I(index),J(index)]-Gap_size-1;
cur=[point;cur];
BW1(point(1),point(2))=0;
[I,J]=find(BW1(point(1)-Gap_size:point(1)+Gap_size,point(2)-Gap_size:point(2)+Gap_size)==1);
end
if size(cur,1)>(size(BW,1)+size(BW,2))/25
cur_num=cur_num+1;
curve{cur_num}=cur-Gap_size;
end
[r,c]=find(BW1==1);
end
for i=1:cur_num
curve_start(i,:)=curve{i}(1,:);
curve_end(i,:)=curve{i}(size(curve{i},1),:);
if (curve_start(i,1)-curve_end(i,1))^2+...
(curve_start(i,2)-curve_end(i,2))^2<=32
curve_mode(i,:)='loop';
else
curve_mode(i,:)='line';
end
BW_edge(curve{i}(:,1)+(curve{i}(:,2)-1)*L)=1;
end
% figure;
% imshow(~BW_edge)
% title('图像轮廓')
% imwrite(~BW_edge,'edge.jpg');
function cout=get_corner(curve,curve_start,curve_end,curve_mode,curve_num,BW,sig,Endpoint,C,T_angle)
corner_num=0;
cout=[];
GaussianDieOff = .0001;
pw = 1:30;
ssq = sig*sig;
width = max(find(exp(-(pw.*pw)/(2*ssq))>GaussianDieOff));
if isempty(width)
width = 1;
end
t = (-width:width);
gau = exp(-(t.*t)/(2*ssq))/(2*pi*ssq);
gau=gau/sum(gau);
for i=1:curve_num;
x=curve{i}(:,1);
y=curve{i}(:,2);
W=width;
L=size(x,1);
if L>W
% 计算曲率
if curve_mode(i,:)=='loop'
x1=[x(L-W+1:L);x;x(1:W)];
y1=[y(L-W+1:L);y;y(1:W)];
else
x1=[ones(W,1)*2*x(1)-x(W+1:-1:2);x;ones(W,1)*2*x(L)-x(L-1:-1:L-W)];
y1=[ones(W,1)*2*y(1)-y(W+1:-1:2);y;ones(W,1)*2*y(L)-y(L-1:-1:L-W)];
end
xx=conv(x1,gau);
xx=xx(W+1:L+3*W);
yy=conv(y1,gau);
yy=yy(W+1:L+3*W);
Xu=[xx(2)-xx(1) ; (xx(3:L+2*W)-xx(1:L+2*W-2))/2 ; xx(L+2*W)-xx(L+2*W-1)];
Yu=[yy(2)-yy(1) ; (yy(3:L+2*W)-yy(1:L+2*W-2))/2 ; yy(L+2*W)-yy(L+2*W-1)];
Xuu=[Xu(2)-Xu(1) ; (Xu(3:L+2*W)-Xu(1:L+2*W-2))/2 ; Xu(L+2*W)-Xu(L+2*W-1)];
Yuu=[Yu(2)-Yu(1) ; (Yu(3:L+2*W)-Yu(1:L+2*W-2))/2 ; Yu(L+2*W)-Yu(L+2*W-1)];
K=abs((Xu.*Yuu-Xuu.*Yu)./((Xu.*Xu+Yu.*Yu).^1.5));
K=ceil(K*100)/100;
%找到曲率最大的轮廓候选点
extremum=[];
N=size(K,1);
n=0;
Search=1;
for j=1:N-1
if (K(j+1)-K(j))*Search>0
n=n+1;
extremum(n)=j; % 在极值点, 奇数点最小,偶数点最大
Search=-Search;
end
end
if mod(size(extremum,2),2)==0
n=n+1;
extremum(n)=N;
end
n=size(extremum,2);
flag=ones(size(extremum));
%与自适应局部阈值去圆角比较
for j=2:2:n
[x,index1]=min(K(extremum(j):-1:extremum(j-1)));
[x,index2]=min(K(extremum(j):extremum(j+1)));
ROS=K(extremum(j)-index1+1:extremum(j)+index2-1);
K_thre(j)=C*mean(ROS);
if K(extremum(j))<K_thre(j)
flag(j)=0;
end
end
extremum=extremum(2:2:n);
flag=flag(2:2:n);
extremum=extremum(find(flag==1));
%根据边界噪声和细节检查轮廓去掉假轮廓
flag=0;
smoothed_curve=[xx,yy];
while sum(flag==0)>0
n=size(extremum,2);
flag=ones(size(extremum));
for j=1:n
if j==1 & j==n
ang=curve_tangent(smoothed_curve(1:L+2*W,:),extremum(j));
elseif j==1
ang=curve_tangent(smoothed_curve(1:extremum(j+1),:),extremum(j));
elseif j==n
ang=curve_tangent(smoothed_curve(extremum(j-1):L+2*W,:),extremum(j)-extremum(j-1)+1);
else
ang=curve_tangent(smoothed_curve(extremum(j-1):extremum(j+1),:),extremum(j)-extremum(j-1)+1);
end
if ang>T_angle & ang<(360-T_angle)
flag(j)=0;
end
end
if size(extremum,2)==0
extremum=[];
else
extremum=extremum(find(flag~=0));
end
end
extremum=extremum-W;
extremum=extremum(find(extremum>0 & extremum<=L));
n=size(extremum,2);
for j=1:n
corner_num=corner_num+1;
cout(corner_num,:)=curve{i}(extremum(j),:);
end
end
end
% 添加端点
if Endpoint
for i=1:curve_num
if size(curve{i},1)>0 & curve_mode(i,:)=='line'
% 起点与检测到的轮廓
compare_corner=cout-ones(size(cout,1),1)*curve_start(i,:);
compare_corner=compare_corner.^2;
compare_corner=compare_corner(:,1)+compare_corner(:,2);
if min(compare_corner)>25 % 添加结束点到未检测到的轮廓
corner_num=corner_num+1;
cout(corner_num,:)=curve_start(i,:);
end
% 端点比较
compare_corner=cout-ones(size(cout,1),1)*curve_end(i,:);
compare_corner=compare_corner.^2;
compare_corner=compare_corner(:,1)+compare_corner(:,2);
if min(compare_corner)>25
corner_num=corner_num+1;
cout(corner_num,:)=curve_end(i,:);
end
end
end
end
function ang=curve_tangent(cur,center)
for i=1:2
if i==1
curve=cur(center:-1:1,:);
else
curve=cur(center:size(cur,1),:);
end
L=size(curve,1);
if L>3
if sum(curve(1,:)~=curve(L,:))~=0
M=ceil(L/2);
x1=curve(1,1);
y1=curve(1,2);
x2=curve(M,1);
y2=curve(M,2);
x3=curve(L,1);
y3=curve(L,2);
else
M1=ceil(L/3);
M2=ceil(2*L/3);
x1=curve(1,1);
y1=curve(1,2);
x2=curve(M1,1);
y2=curve(M1,2);
x3=curve(M2,1);
y3=curve(M2,2
评论0