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