function [cout,marked_img]=corner(varargin)
% CORNER Find corners in intensity image.
%
% CORNER works by the following step:
% 1. Apply the Canny edge detector to the gray level image and obtain a
% binary edge-map.
% 2. Extract the edge contours from the edge-map, fill the gaps in the
% contours.
% 3. Compute curvature at a low scale for each contour to retain all
% true corners.
% 4. All of the curvature local maxima are considered as corner
% candidates, then rounded corners and false corners due to boundary
% noise and details were eliminated.
% 5. End points of line mode curve were added as corner, if they are not
% close to the above detected corners.
%
% Syntax :
% [cout,marked_img]=corner(I,C,T_angle,sig,H,L,Endpiont,Gap_size)
%
% Input :
% I - the input image, it could be gray, color or binary image. If I is
% empty([]), input image can be get from a open file dialog box.
% C - denotes the minimum ratio of major axis to minor axis of an ellipse,
% whose vertex could be detected as a corner by proposed detector.
% The default value is 1.5.
% T_angle - denotes the maximum obtuse angle that a corner can have when
% it is detected as a true corner, default value is 162.
% Sig - denotes the standard deviation of the Gaussian filter when
% computeing curvature. The default sig is 3.
% H,L - high and low threshold of Canny edge detector. The default value
% is 0.35 and 0.
% Endpoint - a flag to control whether add the end points of a curve
% as corner, 1 means Yes and 0 means No. The default value is 1.
% Gap_size - a paremeter use to fill the gaps in the contours, the gap
% not more than gap_size were filled in this stage. The default
% Gap_size is 1 pixels.
%
% Output :
% cout - a position pair list of detected corners in the input image.
% marked_image - image with detected corner marked.
%
% Examples
% -------
% I = imread('alumgrns.tif');
% cout = corner(I,[],[],[],0.2);
%
% [cout, marked_image] = corner;
%
% cout = corner([],1.6,155);
%
%
% Composed by He Xiaochen
% HKU EEE Dept. ITSR, Apr. 2005
%
% Algorithm is derived from :
% X.C. He and N.H.C. Yung, ¡°Curvature Scale Space Corner Detector with
% Adaptive Threshold and Dynamic Region of Support¡±, Proceedings of the
% 17th International Conference on Pattern Recognition, 2:791-794, August 2004.
% Improved algorithm is included in ¡°A Corner Detector based on Global and Local
% Curvature Properties¡±and submitted to Optical Engineering.
[I,C,T_angle,sig,H,L,Endpoint,Gap_size] = parse_inputs(varargin{:});
if size(I,3)==3
I=rgb2gray(I); % Transform RGB image to a Gray one.
end
tic
BW=EDGE(I,'canny',[L,H]); % Detect edges
time_for_detecting_edge=toc
tic
[curve,curve_start,curve_end,curve_mode,curve_num]=extract_curve(BW,Gap_size); % Extract curves
time_for_extracting_curve=toc
tic
cout=get_corner(curve,curve_start,curve_end,curve_mode,curve_num,BW,sig,Endpoint,C,T_angle); % Detect corners
time_for_detecting_corner=toc
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('Detected corners')
imwrite(marked_img,'corner.jpg');
function [curve,curve_start,curve_end,curve_mode,cur_num]=extract_curve(BW,Gap_size)
% Function to extract curves from binary edge map, if the endpoint of a
% contour is nearly connected to another endpoint, fill the gap and continue
% the extraction. The default gap size is 1 pixles.
[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
% Extract edge towards another direction
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(1)
imshow(~BW_edge)
title('Edge map')
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
% Calculate curvature
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;
% Find curvature local maxima as corner candidates
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; % In extremum, odd points is minima and even points is maxima
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));
% Compare with adaptive local threshold to remove round corners
for j=2:2:n
%I=find(K(extremum(j-1):extremum(j+1))==max(K(extremum(j-1):extremum(j+1))));
%extremum(j)=extremum(j-1)+round(mean(I))-1; % Regard middle point of plateaus as maxima
[x,index1]=min(K(extremum(j):-1:extremum(j-1)));
[x
- 1
- 2
前往页