由点坐标拟合圆和计算圆度

由点坐标拟合圆和计算圆度

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;
 }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值