我有一个点的图像,这些点“在视觉上”形成一个闭合的圆。但是,这些点沿此“轮廓”分布不均,导致质心偏斜。我尝试使用findContours,但找不到闭合线。

有没有简单的解决方案?

编辑:
这些点存储在x和相应y坐标的 vector 中,我使用cv::circle对其进行了绘制。

图片:白色+红色=整个 vector (720点),红色= vector 的前半部分(360点)

c++ - 不规则点分布的质心-LMLPHP

原始图片:

c++ - 不规则点分布的质心-LMLPHP

最佳答案

您可以使用minEnclosingCircle查找包含所有点的最小圆。

您获得center作为函数的输出值:

void minEnclosingCircle(InputArray points, Point2f& center, float& radius)

更新

我尝试了一些不同的事情。 我假设您知道您的最终形状将是一个圆形
  • minEnclosingCircle
  • boundingRect
  • fitEllipse

  • 最好的结果(在此图像中)似乎是fitEllipse

    结果

    minEnclosingCircle:

    c++ - 不规则点分布的质心-LMLPHP

    boundingRect:

    c++ - 不规则点分布的质心-LMLPHP

    fitEllipse:

    c++ - 不规则点分布的质心-LMLPHP

    码:
    #include <opencv2\opencv.hpp>
    #include <vector>
    
    using namespace std;
    using namespace cv;
    
    int main()
    {
        Mat1b img = imread("path_to_image", IMREAD_GRAYSCALE);
    
        vector<Point> points;
        findNonZero(img, points);
    
        Mat3b res;
        cvtColor(img, res, CV_GRAY2BGR);
    
        //////////////////////////////////
        // Method 1: minEnclosingCircle
        //////////////////////////////////
    
        /*Point2f center;
        float radius;
        minEnclosingCircle(points, center, radius);
    
        circle(res, center, radius, Scalar(255,0,0), 1);
        circle(res, center, 5, Scalar(0,255,0), 1);*/
    
    
        //////////////////////////////////
        // Method 2: boundingRect
        //////////////////////////////////
    
        /*Rect bbox = boundingRect(points);
    
        rectangle(res, bbox, Scalar(0,255,255));
        circle(res, Point(bbox.x + bbox.width/2, bbox.y + bbox.height/2), 5, Scalar(0,0,255));*/
    
    
        //////////////////////////////////
        // Method 3: fit ellipse
        //////////////////////////////////
    
        RotatedRect ell = fitEllipse(points);
        ellipse(res, ell, Scalar(255,255,0));
        circle(res, ell.center, 5, Scalar(255,0,255));
    
        return 0;
    }
    

    10-06 06:57