如何判断轮廓是否为圆?【废弃】

   本文废弃,算法更新于:如何判断轮廓是否为圆(算法更新)
   判断一个轮廓是否为圆?这看似简单的问题,在opencv中并没有现成的函数。当我真正想运用的时候,却发现还是有许多内容在里面的。
      
       比如这幅图片,由于瓶口是有缺陷的,造成找到的最大外轮廓不闭合。那么该如何判断这个轮廓是否是圆了。
     我认为从两点来考虑。
      一个是圆的定义:
   “平面上到定点的距离等于定长的所有点组成的图形叫做圆.定点称为圆心,定长称为半径.”
      那么就来判断当前轮廓到一个定点的距离是否为定长。这里这个定点就可以采用外接圆圆心。而这里的度量是标准差。
       经过试验发现,对于这些有缺陷的情况,其标准差都是比较大的(一般大于5),而对于没有缺陷的情况来说,其标准差都比较小(小于1)。
       但是这并不能完全地解决问题,比如存在这样的情况,其轮廓上所有点到定点的标准差也是不大的,但是这个轮廓没有构成一个闭合曲线,所以也没有构成圆。

     
  1.    //根据轮廓点和圆心计算方差
  2. float ComputeVariance(std::vector<cv::Point> theContour,Point2f theCenter)
  3. {
  4.     int a[65535],n;
  5.     float aver,s;
  6.     float sum=0,e=0;
  7.     n = theContour.size();
  8.     for(int i=0;i<n;i++)
  9.     {
  10.         a[i] = GetDistance(theContour[i],theCenter);
  11.         sum+=a[i];
  12.     }
  13.     aver=sum/n;
  14.     for(int i=0;i<n;i++)
  15.         e+=(a[i]-aver)*(a[i]-aver);
  16.     e/=n-1;
  17.     s=sqrt(e);
  18.     return e;
  19. }
 
        那么二点就是曲线闭合的定义.
      闭曲线:起点与终点重合的曲线。平面(或空间)中的闭曲线即为单位圆周到平面(或空间)中的连续映射的像。
      不是很好理解,但是可以这样简化,就是对于闭曲线中的任意一点,遍历闭曲线,都能够回到这一点。换句话说,就是不存在“端点”。这里可以再转换为这样的理解:
        “对于闭曲线中的所有点,除了它本身之外,和这个点距离为最小值(比如1)的点都有两个。”
  1. //判断轮廓是否闭合。闭合曲线返回为0
  2. intComputeClose(std::vector<cv::Point>MaxContour)
  3. {
  4. //TODO 计算第一个点和最后一个点相对于圆心的角度.最后变成计算这两点的距离
  5. int itmp =0;
  6. int iret =0;
  7. for(int i=0;i<MaxContour.size();i++)
  8. {
  9. for(int j=0;j<MaxContour.size();j++)
  10. {
  11. if(i!=j)
  12. {
  13. if(GetDistance(MaxContour[i],MaxContour[j])<1)
  14. {
  15. itmp++;
  16. }
  17. }
  18. }
  19. if(itmp ==1)//存在端点
  20. {
  21. iret ++;
  22. }
  23. itmp=0;
  24. }
  25. return iret;
  26. }
 
      小结一下:数学还是很强的,很多时候,借助定义本身,能够解决问题。
        
     



原文地址:https://www.cnblogs.com/jsxyhelu/p/4503900.html