1. 椭圆拟合
轮廓的椭圆拟合是指用椭圆来近似轮廓的形状。当这个椭圆的长轴和短轴相等时,它就是一个圆。
椭圆拟合的基本思路是:对于给定平面上的一组样本点,寻找一个椭圆,使其尽可能接近这些样本点。也就是说,将图像中的一组数据以椭圆方程为模型进行拟合,使某一椭圆方程尽量满足这些数据,并求出该椭圆方程的各个参数。
椭圆拟合有以下几种常用方法:
最小二乘法:最小二乘法是基于最小化拟合误差的思想,通过迭代的方法求解椭圆参数。该方法的优点是简单易实现,缺点是计算量大,当轮廓点数较多时,容易出现收敛问题。
极大似然法:极大似然法是基于概率统计的思想,通过最大化椭圆模型的似然函数求解椭圆参数。该方法的优点是收敛速度快,计算量小,缺点是对初始值敏感。
最小距离法:最小距离法是基于最小化样本点到椭圆的距离的思想,通过迭代的方法求解椭圆参数。该方法的优点是计算量小,收敛速度快,缺点是对初始值敏感。
在 OpenCV 提供了三种 fitEllipse()、fitEllipseAMS()、fitEllipseDirect() 函数实现椭圆拟合。
RotatedRect fitEllipse( InputArray points );
RotatedRect fitEllipseAMS( InputArray points );
RotatedRect fitEllipseDirect( InputArray points );
其输出的 RotatedRect 包含了
椭圆的中心位置
长轴的直径
短轴的直径
旋转角度
OpenCV 提供的这三个函数还是有一定区别的:
函数 | 算法 | 优点 | 缺点 |
---|---|---|---|
fitEllipse() | 最小二乘法 | 简单易实现 | 计算量大,收敛问题 |
fitEllipseAMS() | 改进的最小二乘法 | 收敛速度快,精度高 | 计算量略大 |
fitEllipseDirect() | 直接求解 | 计算量最小 | 对初始值敏感 |
在实际应用中,可以根据具体情况选择合适的椭圆拟合函数。如果对拟合精度要求较高,可以使用 fitEllipseAMS() 函数。如果对计算速度要求较高,可以使用 fitEllipseDirect() 函数。
下面的例子展示了找到有效的轮廓后,对这些轮廓进行椭圆拟合。
#include "opencv2/imgproc.hpp"
#include "opencv2/highgui.hpp"
using namespace std;
using namespace cv;
bool ascendSort(vector<Point> a,vector<Point> b)
{
return contourArea(a) > contourArea(b);
}
int main(int argc, char **argv) {
Mat src = imread(".../test.jpg");
im