function [circleParaXYR,beginPosi,pNum,pSetXY] = randHoughCircle(Imbinary,pRange)
% RANDHOUGHCIRCLE - detects circles in a binary image using random Hough transform.
%
% Comments:
% Function uses random Hough Transform to detect circles in a binary image.
%
% Upper left corner of image is the origin of coordinate system.
% __________________ x, column, jj(cycle variable)
% | |
% | |
% | |
% | |
% | |
% ------------------
% y,row, ii(cycle variable)
%
% Usage: [circleParaXYR,beginPosi,pNum,pSetXY] = randHoughCircle(Imbinary,pRange)
%
% Arguments:
% Imbinary - a binary image. image pixels that have value equal to 1 are
% interested pixels for RANDHOUGHCIRCLE function.
%
% pRange - [xmin,xmax,ymin,ymax,rmin,rmax]the range of the parameters of the circles.
% Default is [-0.5,0.1,0.45,0.55,0.75,1.5]
%
% Returns:
% circleParaXYR - The parameters of detected circles. If n circles are detected, circleParaXYR is a n*3 matrix. circleParaXYR(n,1)
% circleParaXYR(n,2),circleParaXYR(n,3) are the x coordinates, the y coordinates of the circle center, and the
% radius of the nth detected circle.
% pSetXY - Points set which is on the detected circles.
% beginPosi - A vector with n elements if n circles are detected. beginPosi(n) is the position of the first point in pSetXY
% of the nth detected circle.
% pNum - Point number on circles. pNum(n) is the point number of the nth detected circle
% Record of revisions:
% Data Programmer Description of change
% ========== ========== =====================
% 22/10/2007 Joe Original code
%
% If the input parameter number is less than 2, then the fault value of the pRange is used.
if nargin<2 pRange = [0,1,0,1,0.005,1]; end
% Determine the size of the input image
imSize = size(Imbinary);
% Parameter setting:
T_f = 80000; % Denotes the number of failures that we can tolerate
T_min = 30; % If there are less than T-min pixels in V, we stop the task of circle detection.
T_a = 5; % The distance between any two agent pixels of the possible circle should be larger than T_a.
T_d = 3; % The ditance threshold
T_r = 0.6; % The ratio threhold
T_c = 3;
% T_r = 0.4;
resolution = 1;
% Define the Accumulator
xmin = round(pRange(1) * imSize(1));
xmax = round(pRange(2) * imSize(1));
ymin = round(pRange(3) * imSize(1));
ymax = round(pRange(4) * imSize(1));
rmin = round(pRange(5) * imSize(1));
rmax = round(pRange(6) * imSize(1));
dex = round((pRange(2) * imSize(1)-pRange(1)*imSize(1))/resolution);
dey = round((pRange(4) * imSize(1)-pRange(3)*imSize(1))/resolution);
der = round((pRange(6) * imSize(1)-pRange(5)*imSize(1))/resolution);
Accumulator = zeros(dex, dey, der);
[yIndex xIndex] = find(Imbinary); % Find the edge point in the input image
f = 1; % f is the times of trying
% the following variables is defined to store the parameters of the
% detected circles.
circleParaXYR = [];
pSetXY = [];
beginPosi = [];
pNum = [];
% If the trying number is less than T_f, then draw three points to
% accumulate in the Accumulator
while f < T_f && length(xIndex) > T_min
% Draw 3 points randomly from the point set
zb = round( (length(xIndex)-3) * rand(1) )+1;
xp1 = xIndex(zb);
yp1 = yIndex(zb);
zb = round( (length(xIndex)-3)*rand(1) )+1;
xp2 = xIndex(zb);
yp2 = yIndex(zb);
zb = round( (length(xIndex)-3)*rand(1) )+1;
xp3 = xIndex(zb);
yp3 = yIndex(zb);
% Test whether the three points are colinear
if (xp2-xp1)*(yp3-yp1) - (xp3-xp1)*(yp2-yp1)~=0.0 && ...
(yp2-yp1)^2+(xp2-xp1)^2 > T_a^2 &&...
(yp3-yp1)^2+(xp3-xp1)^2 > T_a^2 &&...
(yp3-yp2)^2+(xp3-xp2)^2 > T_a^2
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Calculate the parameters of the circle determined by the randomly drawn 3 points.
% Calculte the x coordinate of the center of the circle
xCenterS = (xp2^2 + yp2^2 - xp1^2 - yp1^2) * (2*yp3 - 2*yp1)...
- (xp3^2 + yp3^2 - xp1^2 - yp1^2) * (2*yp2 - 2*yp1);
xCenterX = 4*((xp2 - xp1)*(yp3 - yp1) - (xp3 - xp1)*(yp2 - yp1));
xCenter = xCenterS / xCenterX;
% Calculte the y coordinate of the center of the circle
yCenterS = (2*xp2 - 2*xp1) * (xp3^2 + yp3^2 - xp1^2 - yp1^2)...
- (2*xp3 - 2*xp1) * (xp2^2 + yp2^2 - xp1^2 - yp1^2);
yCenter = yCenterS / xCenterX;
% Calculate the radius of the circle
r = sqrt( (xp1 - xCenter)^2 + (yp1 - yCenter)^2 );
% Voting
if r>rmin+4 && r<rmax-4 && xCenter > xmin+4 && xCenter < xmax-4 && yCenter > ymin+4 && yCenter < ymax-4
Accumulator(round((xCenter - xmin)/resolution),round((yCenter - ymin)/resolution),round((r - rmin)/resolution))...
=Accumulator(round((xCenter - xmin)/resolution),round((yCenter - ymin)/resolution),round((r - rmin)/resolution)) + 1;
% If the value of cell of the Accumulator is larger than T_c, then verificate if it is a real circle
if Accumulator(round((xCenter - xmin)/resolution),round((yCenter - ymin)/resolution),round((r - rmin)/resolution)) == T_c
% numPB is the number of the points belonging to the candidate circle
numPB = 0;
xIndexTem = [];yIndexTem = []; pxTem = []; pyTem = [];
for cnt = 1:length(xIndex)
% dTem is the distance between the point to the candidate circle
dTem = abs(sqrt((xCenter-xIndex(cnt))^2+(yCenter-yIndex(cnt))^2)-r);
if dTem<T_d
numPB = numPB+1;
pxTem = [pxTem,xIndex(cnt)];
pyTem = [pyTem,yIndex(cnt)];
else
yIndexTem = [yIndexTem;yIndex(cnt)];
xIndexTem = [xIndexTem;xIndex(cnt)];
end
end
if numPB>6.28*r*T_r % A real circle is found.
% Renew the point set by removing the points belonging to the new found circle
xIndex = xIndexTem;
yIndex = yIndexTem;
circleParaXYR = [circleParaXYR; xCenter, yCenter, r]; % Store the parameters of the detected circle
beginPosi = [beginPosi;(size(pSetXY,1)+1)]; % Store the beginning position of the points in the set
- 1
- 2
- 3
前往页