由点坐标拟合圆和计算圆度
1.根据坐标点拟合圆
最小二乘法拟合圆
void FitCircle(const vector<Point> pts,double& circleX,double& circleY,double& radius)
{
circleX=0;
circleY=0;
radius=0;
if(pts.size()<3)
{
return;
}
int i=0;
double X1=0,Y1=0,X2=0,Y2=0,X3=0,Y3=0;
double X1Y1=0,X1Y2=0,X2Y1=0;
for (i=0;i<pts.size();i++)
{
X1+=pts.at(i).x;
Y1+=pts.at(i).y;
X2+=std::pow(pts.at(i).x*1.0,2);
Y2+=std::pow(pts.at(i).y*1.0,2);
X3+=std::pow(pts.at(i).x*1.0,3);
Y3+=std::pow(pts.at(i).y*1.0,3);
X1Y1+=pts.at(i).x*pts.at(i).y;
X1Y2+=pts.at(i).x*std::pow(pts.at(i).y*1.0,2);
X2Y1+=std::pow(pts.at(i).x*1.0,2)*pts.at(i).y;
}
double C,D,E,G,H,N;
double a,b,c;
N = pts.size();
C = N*X2 - X1*X1;
D= N*X1Y1 - X1*Y1;
E = N*X3+N*X1Y2-(X2+Y2)*X1;
G = N*Y2 - Y1*Y1;
H = N*X2Y1 + N*Y3-(X2+Y2)*Y1;
a = (H*D-E*G)/(C*G-D*D);
b = (H*C - E*D)/(D*D-G*C);
c = -(a*X1+b*Y1+X2+Y2)/N;
circleX = a/(-2);
circleY = b/(-2);
radius = std::sqrt(a*a+b*b-4*c)/2;
}
2.圆度计算方式1
计算区域的面积和近似最小外接圆的面积的比值
double CalCircularity(const vector<Point> contours,double area)
{
double dCircular = 0;
int nCount = contours.size();
double dSumX = 0, dSumY = 0;
for (size_t i = 0; i < nCount; i++)
{
dSumX += contours.at(i).x;
dSumY += contours.at(i).y;
}
double dDistSum = 0;
double dtemp = 0;
double meanX = dSumX * 1.0 / nCount;
double meanY = dSumY * 1.0 / nCount;
double dMaxDist=0;
for (size_t i = 0; i < nCount; i++)
{
dtemp = pow(contours.at(i).x - meanX, 2) + pow(contours.at(i).y - meanY, 2);
dtemp=sqrt(dtemp);
if (dMaxDist<dtemp)
{
dMaxDist = dtemp;
}
}
double dRatio = area/(dMaxDist*dMaxDist*CV_PI);
dCircular = STDMIN(1,dRatio);
return dCircular;
}
3.圆度计算方式2
计算区域轮廓上各点到区域中心的平均距离(Distance)与这些距离的标准差(Sigma)之间的关系
double CalRoundess(const vector<Point> contours)
{
double dCircular = 0;
int nCount = contours.size();
double dSumX = 0, dSumY = 0;
for (size_t i = 0; i < nCount; i++)
{
dSumX += contours.at(i).x;
dSumY += contours.at(i).y;
}
double dDistSum = 0;
double dtemp = 0;
double meanX = dSumX * 1.0 / nCount;
double meanY = dSumY * 1.0 / nCount;
for (size_t i = 0; i < nCount; i++)
{
dtemp = pow(contours.at(i).x - meanX, 2) + pow(contours.at(i).y - meanY, 2);
dDistSum += sqrt(dtemp);
}
double dMeanDist = dDistSum * 1.0 / nCount;
double dSigmaSum = 0;
for (size_t i = 0; i < nCount; i++)
{
dtemp = pow(contours.at(i).x - meanX, 2) + pow(contours.at(i).y - meanY, 2);
dSigmaSum +=pow( sqrt(dtemp)- dMeanDist,2);
}
double dMeanSigma = sqrt(dSigmaSum * 1.0 / nCount);
dCircular = 1 - dMeanSigma / dMeanDist;
return dCircular;
}