You are on page 1of 4

Simple circle fitting1

Generic circle equation

( 1 )2 + ( 2 )2 = 2 , (1)

can be expanded as

2 21 + 1 2 + 2 22 + 2 2 = 2 (2)

Re-arrange (2)

2 + 2 21 22 + 1 2 + 2 2 2 = 0 (3)

If vector = [(1) (2)(3)] , and Eq.(3) is re-written as

2 + 2 (1) (2) + (3) = 0 (4)


or

(1) + (2) + (3) = 2 + 2 (5)

then we have the coordinate of the fitted parameters c1, c2 and r in Eq.(1) as

(1) = 21 (2) = 22
(1) (2)
= =
2 2
2
(3) = 1 + 2 2 2 , (6)

(1)2 (2)2
= + (3)
4 4

If there are m pairs of measured points to be fitted of (1 , 1 ) , (2 , 2 ) , ,


( , ) or ( , ) where = 1, 2,3, , , then all these points must fulfil the circle
equation in Eq(1) to (3) or

2 + 2 2 1 2 2 + 1 2 + 2 2 2 = 0 , = 1,2, , (7)

or written in the format of Eq.(5)all the points are arranged as follows

1
Prepared by Taufiq Widjanarko t.widjanarko@lboro.ac.uk (July16)

1
(1)1 + (2)1 + (3) = 1 2 + 1 2
(1)2 + (2)2 + (3) = 2 2 + 2 2
(6)
(1) + (2) + (3) = + 2
2

which can be solved simultaneously using matrix. Now Eq.(6) can be written as

1 1 1 12 + 12
(1)
2 1 2 2
[ 2 ] [(2)] = 2 + 2
(7)
1 (3) 2
[ + 2
]

1 1 1 12 + 12
2 2 1 2 2
If matrices [ ], and 2 + 2 , then Eq.(7) can be written as

1 2
[ + 2
]

= (8)

or vector can be calculated as

=
(9)

= =

where is the inverse of matrix and I is the identity matrix.

Note that Eq(9) can be solved provided that matrix is not a singular matrix (or the
inverse matrix exists).

Once the vector is solved, all circle fitting parameters c1, c2 and r in Eq.(1) can be
calculated using relations in Eq.(6).

Computationally, for example in Matlab, Eq.(9) can be solved using command

a = C\B (10)

Example of Matlab snippet for circle fitting using above approach is circfit.m from
Izhak Bucher2. First line after the comments x=x(:); y=y(:); is to arrange the input
data to the function into arrays x and y . The second line is the inverse operation in
Eq.(10) where the first part [x y ones(size(x))] is to arrange the data column
arrays x and y as adjacently column vectors followed by column vector ones of

2
The code is available at Matlab codes/files exchange repository Matlab Exchange at
http://uk.mathworks.com/matlabcentral/fileexchange/5557-circle-fit/content/circfit.m (retrieved on 26
July 2016)

2
the size of x (or y as they both of the same size) to complete the left matrix in
Eq.(7). The term in the second line of the code [-(x.^2+y.^2)]; is equal to the
vector column to the right of equal sign in Eq.(7). The last three lines are to calculate
the circle fitting parameters c1, c2 and r , which are calculated using relations in Eq.(6).
function [xc,yc,R,a] = circfit(x,y)
%
% [xc yx R] = circfit(x,y)
%
% fits a circle in x,y plane in a more accurate
% (less prone to ill condition )
% procedure than circfit2 but using more memory
% x,y are column vector where (x(i),y(i)) is a measured point
%
% result is center point (yc,xc) and radius R
% an optional output is the vector of coeficient a
% describing the circle's equation
%
% x^2+y^2+a(1)*x+a(2)*y+a(3)=0
%
% By: Izhak bucher 25/oct /1991,
x=x(:); y=y(:);
a=[x y ones(size(x))]\[-(x.^2+y.^2)];
xc = -.5*a(1);
yc = -.5*a(2);
R = sqrt((a(1)^2+a(2)^2)/4-a(3));

Fitting result using the above code (circfit.m ) is shown in Fig.1. The caller
program try_circ_fit.m 3 supplies the fitting function (circfit.m ) with the
example of measured data and plots the fitting results in Fig.1. Fitting results i.e.
shifted circle origin in x and y coordinates and radius (c1, c2 ) and r , respectively are
displayed on the output plot in the figure.
%try_circ_fit
%
% IB
%
% revival of a 13 years old code

% Create data for a circle + noise

th = linspace(0,2*pi,20)';
R=1.1111111;
sigma = R/10;
x = R*cos(th)+randn(size(th))*sigma;
y = R*sin(th)+randn(size(th))*sigma;

plot(x,y,'o'), title(' measured points')


pause(1)

% reconstruct circle from data


[xc,yc,Re,a] = circfit(x,y);
xe = Re*cos(th)+xc; ye = Re*sin(th)+yc;

3
The caller code is available at http://uk.mathworks.com/matlabcentral/fileexchange/5557-circle-
fit/content/circfit.m (retrieved on 26 July 2016)

3
plot(x,y,'o',[xe;xe(1)],[ye;ye(1)],'-.',R*cos(th),R*sin(th)),
title(' measured fitted and true circles')
legend('measured','fitted','true')
text(xc-R*0.9,yc,sprintf('center (%g , %g ); R=%g',xc,yc,Re))
xlabel x, ylabel y
axis equal

Figure 1. Output of circle fitting using circfit.m

Once again please note that this methods works only if the measured data ( , )
where = 1, 2,3, , forms a non-singular matrix.

You might also like