【问题标题】:how to check if a contour is an ellipse?如何检查轮廓是否为椭圆?
【发布时间】:2012-10-19 15:14:46
【问题描述】:

我正在尝试使用 opencv 检测图像中的椭圆。我找到了包括椭圆和其他一些轮廓的轮廓。

关于如何检查哪些轮廓是椭圆的任何建议?

【问题讨论】:

  • 您能否更具体地说明“大约”的含义?
  • @mathematician1975,我已经上传了图片,嗯,我猜放大约有点太多了,我会改变它!谢谢
  • 查看示例图像,椭圆将是一个闭合轮廓

标签: opencv contour ellipse


【解决方案1】:

如果我理解正确,您已经检测到轮廓,其中一些是椭圆,有些不是,您希望能够确定哪些是椭圆。这样对吗? 如果是,我建议使用cv::fitEllipse()。该文档说它将椭圆拟合到点向量,因此 R 平方是最小的。不幸的是,该函数没有显式返回 R 平方值。您也许可以自己实现它...

作为一种解决方法,您还可以使用以下方法:

  1. 获取轮廓C
  2. 将椭圆 E 拟合到 C
  3. 比较 E 和 C。

要比较它们,您可以使用时刻(参见 cv::moments()cv::matchShapes())。 不过,我认为您在这里不需要不变的时刻。

或者,你可以画出 C 和 E 找出有多少比例的表面重叠。

祝你好运,

【讨论】:

    【解决方案2】:

    fitEllipse 给我们 RotatedRect。

    我们可以使用椭圆的特定属性,可以转换成圆形。

    double is_ellipse( std::vector<cv::Point>  const& cloud, RotatedRect const& rr )
    {
        double distance =0;
    
        for( auto const& point: cloud )
        {
            Point2f unit;
            unit.x = ( ( rr.center.x - point.x  ) * cos( - rr.angle*(3.1415926/180) ) -  ( rr.center.y - point.y  ) * sin( - rr.angle*(3.1415926/180) ) ) * 2 / rr.size.width ;
            unit.y = ( ( rr.center.x - point.x  ) * sin( - rr.angle*(3.1415926/180) ) +  ( rr.center.y - point.y  ) * cos( - rr.angle*(3.1415926/180) ) ) * 2 / rr.size.height;
    
            double len = sqrt( unit.x* unit.x +  unit.y * unit.y );
            distance += fabs( 1- len );
        }
        return distance / cloud.size();
    }
    

    这里用于计算距圆边界的平均距离。 修改其他一些统计函数很容易,例如:最大值、偏差。

    【讨论】:

      【解决方案3】:

      @Ahsan - 您必须遍历所有轮廓并尝试拟合椭圆。如果您发现曲线拟合数学很困难,那么短路径将是

      喜欢 - 遍历每个轮廓 - 丢弃非凸轮廓 - 现在制作当前轮廓的蒙版并使用 cv::matchShapes 函数进行 shapeMatching。

      【讨论】:

        猜你喜欢
        • 2016-12-09
        • 2019-07-08
        • 2012-09-26
        • 1970-01-01
        • 2021-06-10
        • 1970-01-01
        • 1970-01-01
        • 2020-06-15
        相关资源
        最近更新 更多