当前位置: 首页 > article >正文

OpenCV结构分析与形状描述符(12)椭圆拟合函数fitEllipseAMS()的使用

  • 操作系统:ubuntu22.04
  • OpenCV版本:OpenCV4.9
  • IDE:Visual Studio Code
  • 编程语言:C++11

算法描述

围绕一组2D点拟合一个椭圆。

该函数计算出一个椭圆,该椭圆拟合一组2D点。它返回一个内切于该椭圆的旋转矩形。使用了由[260]提出的近似均方差(AMS)方法。

对于椭圆,这个基集是 χ = ( x 2 , x y , y 2 , x , y , 1 ) \chi= \left(x^2, x y, y^2, x, y, 1\right) χ=(x2,xy,y2,x,y,1),这是一个包含六个自由系数的集合 A T = { A xx , A xy , A yy , A x , A y , A 0 } A^T=\left\{A_{\text{xx}},A_{\text{xy}},A_{\text{yy}},A_x,A_y,A_0\right\} AT={Axx,Axy,Ayy,Ax,Ay,A0}然而,要指定一个椭圆,只需要五个数字;主轴和次轴的长度 ( a , b ) (a,b) (a,b),位置 ( x 0 , y 0 ) (x_0,y_0) (x0,y0)以及方向 θ。这是因为基集包含了直线、二次函数、抛物线和双曲线函数以及椭圆函数作为可能的拟合。如果发现拟合是一个抛物线或双曲线函数,则使用标准的 fitEllipse 方法。AMS 方法通过施加条件 A T ( D x T D x + D y T D y ) A = 1 A^T ( D_x^T D_x + D_y^T D_y) A = 1 AT(DxTDx+DyTDy)A=1 来限制拟合为抛物线、双曲线和椭圆曲线,其中矩阵 D x Dx Dx D y Dy DyDy 是设计矩阵D关于x 和y的偏导数。矩阵是通过逐行应用以下规则来形成的,针对点集中的每一个点: D ( i , : ) = { x i 2 , x i y i , y i 2 , x i , y i , 1 } D x ( i , : ) = { 2 x i , y i , 0 , 1 , 0 , 0 } D y ( i , : ) = { 0 , x i , 2 y i , 0 , 1 , 0 } \begin{align*} D(i,:)&=\left\{x_i^2, x_i y_i, y_i^2, x_i, y_i, 1\right\} & D_x(i,:)&=\left\{2 x_i,y_i,0,1,0,0\right\} & D_y(i,:)&=\left\{0,x_i,2 y_i,0,1,0\right\} \end{align*} D(i,:)={xi2,xiyi,yi2,xi,yi,1}Dx(i,:)={2xi,yi,0,1,0,0}Dy(i,:)={0,xi,2yi,0,1,0}
AMS 方法最小化成本函数:
ϵ 2 = A T D T D A A T ( D x T D x + D y T D y ) A T \begin{equation*} \epsilon ^2=\frac{ A^T D^T D A }{ A^T (D_x^T D_x + D_y^T D_y) A^T } \end{equation*} ϵ2=AT(DxTDx+DyTDy)ATATDTDA
通过求解广义特征值问题找到最小成本。
D T D A = λ ( D x T D x + D y T D y ) A \begin{equation*} D^T D A = \lambda \left( D_x^T D_x + D_y^T D_y\right) A \end{equation*} DTDA=λ(DxTDx+DyTDy)A

fitEllipseAMS 是 OpenCV 中用于拟合椭圆的一个函数,它使用了“代数方法”(Algebraic Method)来进行椭圆拟合。相比于 fitEllipse 函数使用的最小二乘法,fitEllipseAMS 更侧重于代数意义上的拟合,适用于某些特定的应用场景。

函数原型


RotatedRect cv::fitEllipseAMS
(
	InputArray 	points
)	

参数

  • points 输入的2D点集,存储在 std::vector<> 或 Mat 中。

代码示例

#include <iostream>
#include <opencv2/opencv.hpp>

using namespace std;
using namespace cv;

int main()
{
    // 创建一个空白图像
    Mat img( 400, 400, CV_8UC3, Scalar( 255, 255, 255 ) );

    // 创建一组2D点
    vector< Point2f > points;
    points.push_back( Point2f( 100, 100 ) );
    points.push_back( Point2f( 200, 100 ) );
    points.push_back( Point2f( 200, 200 ) );
    points.push_back( Point2f( 100, 200 ) );
    points.push_back( Point2f( 150, 150 ) );
    points.push_back( Point2f( 150, 250 ) );
    points.push_back( Point2f( 250, 150 ) );
    points.push_back( Point2f( 250, 250 ) );

    // 拟合椭圆
    RotatedRect ellipse = fitEllipseAMS( points );

    // 获取椭圆的四个顶点
    vector< Point2f > boxPoints;
    boxPoints.resize( 4 );  // 确保boxPoints至少有4个元素
    ellipse.points( boxPoints.data() );

    // 将 Point2f 转换为 Point
    vector< Point > intBoxPoints;
    for ( const auto& pt : boxPoints )
    {
        intBoxPoints.push_back( Point( static_cast< int >( pt.x ), static_cast< int >( pt.y ) ) );
    }

    // 在原图上绘制椭圆
    polylines( img, intBoxPoints, true, Scalar( 0, 0, 255 ), 2, LINE_8 );

    // 绘制点集
    for ( const auto& pt : points )
    {
        circle( img, pt, 5, Scalar( 0, 255, 0 ), -1 );
    }

    // 显示结果
    imshow( "Ellipse Fitting (AMS)", img );
    waitKey( 0 );

    return 0;
}

运行结果

在这里插入图片描述


http://www.kler.cn/a/301116.html

相关文章:

  • 基于YOLOv8深度学习的无人机航拍小目标检测系统(PyQt5界面+数据集+训练代码)
  • 视频融合×室内定位×数字孪生
  • 【插件】重复执行 pytest-repeat
  • docker--工作目录迁移
  • ggplot2-scale_x_continuous()
  • 【会话文本nlp】对话文本解析库pyconverse使用教程版本报错、模型下载等问题解决超参数调试
  • 六种远程控制电脑的方法,第二种方法再适合企业不过了
  • 【python计算机视觉编程——7.图像搜索】
  • 苹果宣布iOS 18正式版9月17日推送:支持27款iPhone升级
  • git为不同的项目设置不同的提交作者
  • 严重干扰的验证码识别系统源码分享
  • spark.sql
  • FaskAPI Web学习
  • 动态规划算法之斐波那契数列详细解读(附带Java代码解读)
  • 陈坤2024行走的力量 走向山野感受距离自然更近的地方
  • 9月→2024年计算机与信息安全国际会议
  • 如何读.Net Framework 的源码?
  • 观众登记2025中国(深圳)国际智能手机供应链展览会
  • 数据分析与挖掘课程相关资源
  • 使用 Python 读取 Excel 数据的详细教程
  • 【C++】关键字、命名空间、输入和输出、缺省参数的深入了解
  • Flutter 使用第三方包加载3d模型
  • SpringTest框架JUnit单元测试用例获取ApplicationContext实例的方法
  • 【数据结构-一维差分】力扣1854. 人口最多的年份
  • 陪玩小程序源码搭建,基于PHP+MySQL陪玩系统app源码
  • 解码未来:H.265与H.266技术对比及EasyCVR视频汇聚平台编码技术优势