我正在尝试使用 opencv 检测图像中的椭圆。我找到了包括椭圆和其他一些轮廓的轮廓。
关于如何检查哪些轮廓是椭圆的任何建议?
如果我理解正确,您已经检测到轮廓,其中一些是椭圆,有些不是,您希望能够确定哪些是椭圆。这样对吗?如果是,我建议使用cv::fitEllipse()
. 该文档说它将椭圆拟合到点向量,因此 R 平方是最小的。不幸的是,该函数没有显式返回 R 平方值。你也许可以自己实现它......
作为一种解决方法,您还可以使用以下方法:
要比较它们,您可以使用矩(参见cv::moments()
和cv::matchShapes()
)。不过,我认为您在这里不需要不变的时刻。
或者,你可以画出 C 和 E 找出有多少比例的表面重叠。
祝你好运,
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();
}
这里用于计算距圆边界的平均距离。修改其他一些统计函数很容易,例如:最大值、偏差。
@Ahsan - 您必须遍历所有轮廓并尝试拟合椭圆。如果您发现曲线拟合数学很困难,那么一条捷径将是
像 - 遍历每个轮廓 - 丢弃非凸轮廓 - 现在制作当前轮廓的蒙版并使用 cv::matchShapes 函数进行 shapeMatching。