1

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

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

4

3 回答 3

3

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

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

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

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

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

祝你好运,

于 2012-10-19T16:54:56.040 回答
0

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();
}

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

于 2017-01-25T09:21:48.360 回答
-1

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

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

于 2015-02-19T10:40:28.433 回答