自己想做一个圆的直径和圆心检测,已经canny边缘提取并进行一次闭运算(边缘提取前已经滤波和灰度化),现在想准确的获得两个圆的直径以及圆心并输出结果,自己第一次做,希望各位前辈能给些思路和解决办法。 谢谢

解决方案 »

  1.   

    仅供参考://////////////////////////////////////////////////////////////////////////
    //判断轮廓是不是一个圆,通过轮廓的面积pi*r*r的差异,判断是不是圆。
    //contour:输入轮廓
    //minRadius: 半径长度至少大于minRadius
    //////////////////////////////////////////////////////////////////////////
    BOOL isCircleContour(vector<Point>& contour,double minRadius)
    {
        BOOL isCircle = FALSE;    //double perimeter = arcLength(contour,TRUE);
        double perimeter = arcLength(contour,FALSE);
    double perimeter2 = arcLength(contour,TRUE);
    Rect rect =boundingRect(contour);
    double r = (rect.width+rect.height)/4.0; //半径约等于轮廓外接矩的边长/2 double area=contourArea(contour); double pi=3.1415926; //cout<<"x/y/width/height\t"<<rect.x<<"  "<<rect.y<<"  "<<rect.width<<"  "<<rect.height<<endl;
    //cout<<"perimeter:FALSE\t"<<perimeter<<endl;
    //cout<<"perimeter2:TRUE\t"<<perimeter2<<endl;
    //cout<<"area:\t"<<area<<endl;
    //cout<<"r: "<<r<<"  计算出周长: "<<2*pi*r<<"  计算出面积: "<<pi*r*r<<endl; double perimeterDiffRatio = fabs(2*pi*r - perimeter)*2.0/(2*pi*r + perimeter) *100;
    double areaDiffRatio = fabs(pi*r*r - area)*2.0/(pi*r*r + area) *100;
    double sideDiffRatio = abs(rect.width-rect.height)*2.0/(rect.width+rect.height)*100; //CString CstrInfo3;
    //CstrInfo3.Format(_T(" perimeterDiffRatio: %f\n areaDiffRatio: %f \n  sideDiffRatio:%f"),perimeterDiffRatio,areaDiffRatio,sideDiffRatio);
    //AfxMessageBox(CstrInfo3); if (r>minRadius)
    {
    cout<<"周长差异百分比:  "<<perimeterDiffRatio<<"%"<<endl;;
    cout<<"面积差异百分比:  "<<areaDiffRatio<<"%"<<endl;
    cout<<"边长差异百分比:  "<<sideDiffRatio<<"%"<<endl;;
    cout<<endl<<endl;
        }    //原始的
        //const double areaDiffThresh = 18.0;       //目前统计的,最大的面积差2.58%
        //const double perimeterDiffThresh = 15;    //目前统计的,最大的周长差5.65%
        //const double sideDiffThresh = 15;     //目前统计的,最大的边长差7.3%
        //const double avgDiffThresh = 15.0;        //三个差异比值的加权平均要求小于5.0;    const double areaDiffThresh = 5;        //目前统计的,最大的面积差2.58%
        const double perimeterDiffThresh =7.25; //目前统计的,最大的周长差5.65%
        const double sideDiffThresh = 10;       //目前统计的,最大的边长差7.3%
        const double avgDiffThresh = 5.0;       //三个差异比值的加权平均要求小于5.0;    double avdDiffRatio = (areaDiffRatio+perimeterDiffRatio+sideDiffRatio)/3.0;    //计算出的轮廓周长是半径的2*pi倍数
        if( (areaDiffRatio <areaDiffThresh)
            && (perimeterDiffRatio <perimeterDiffThresh)
            && (sideDiffRatio <sideDiffThresh)
            &&(avdDiffRatio<avgDiffThresh)
            && (r>minRadius) )
        {
            isCircle = TRUE;
        }    return isCircle;}
      

  2.   

    霍夫变换!网上有代码!不一定非要用opencv
      

  3.   

    这个用Matlab 解决比较方便,二值化,然后用regionprops那个函数,找出局部的面积,中心点等属性