opencv中ArUco模块实践(1)

2024-08-25 06:08
文章标签 模块 实践 opencv aruco

本文主要是介绍opencv中ArUco模块实践(1),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

论文阅读模块将分享点云处理,SLAM,三维视觉,高精地图相关的文章。公众号致力于理解三维视觉领域相关内容的干货分享,欢迎各位加入我,我们一起每天一篇文章阅读,开启分享之旅,有兴趣的可联系微信dianyunpcl@163.com。

aruco标记板的检测与识别

在上一节中我们介绍了aruco单个的标记 板的检测和识别这里我们将介绍aruco标记板的检测和识别的过程。

ArUco的生成与检测

ArUco与AprilTag简介

ArUco标定板是一组标记板的组合,其作用类似于单个标记,因为它为相机提供了单个姿势。最流行的标记板是在同一平面上有所有标记的标定板,因为它很容易打印:

然而,标定板是不限于此情况的,并且可以在任何2d或3d物体上进行布局。

标定板和一组独立标记之间的区别在于,标定板中的标记物中的相对位置是先验的。这使得所有标记的角点可以用于估计相机相对于整个板子的姿势,使用一组独立的标记时,可以单独估计每个标记的姿势,因为您不知道标记物在环境中的相对位置。

使用标定板的主要好处是:

  • 姿态估计更为通用,只需要一些标记就可以进行姿态估计,因此,即使存在遮挡或局部视图,也可以计算姿势。

  • 由于采用了更多的点对应(标记角点),因此获得的姿势通常更精确。

ArUco模块允许使用标定板。主类是cv::aruco::Board类,它定义了标定板布局的函数:

class Board {
public:
std::vector<std::vector<cv::Point3f> > objPoints;
cv::aruco::Dictionary dictionary;
std::vector<int> ids;};

Board类型的对象有三个参数:

  • objPoints结构是三维板参考系统中的角点位置列表,即其布局。对于每个标记,其四个角按标准顺序存储,即顺时针顺序并从左上角开始。

  • dictionary参数指示板标记属于哪个标记字典。

  • 最后,ids结构指示objPoints中每个标记相对于指定字典的标识符。

标定板的检测

标记板检测与标准标记检测类似。唯一的区别在于姿势估计步骤。事实上,要使用标记板,在估计板姿势之前,应该先进行标准的标记检测。

aruco模块提供了一个特定的函数estimatePoseBoard(),用于对标记板执行姿势估计:

cv::Mat inputImage;
// camera parameters are read from somewhere
cv::Mat cameraMatrix, distCoeffs;
readCameraParameters(cameraMatrix, distCoeffs);
// assume we have a function to create the board objectcv::aruco::Board board = createBoard();...vector< int > markerIds;
vector< vector<Point2f> > markerCorners;
cv::aruco::detectMarkers(inputImage, board.dictionary, markerCorners, markerIds);
// if at least one marker detectedif(markerIds.size() > 0) {cv::Vec3d rvec, tvec;int valid = cv::aruco::estimatePoseBoard(markerCorners, markerIds, board, cameraMatrix, distCoeffs, rvec, tvec);}

estimatePoseBoard的参数为:

  • markerCorners和markerIds:detectMarkers()函数中检测到的标记的结构。

  • board:定义board布局及其id的board对象

  • cameraMatrix和distcoefs:姿态估计所需的摄像机校准参数。

  • rvec和tvec:董事会的估计姿势。如果不为空,则视为初始猜测。

  • 函数返回用于估计棋盘姿势的标记总数。注意,不应该使用markerCorners和markerIds中提供的所有标记,因为只考虑Board::ids结构中列出了其id的标记。

  • drawAxis() 函数的作用是:检查获得的姿势。

标记板带有坐标系可视化的结果

被遮挡的标记物的检测并带有坐标系的可视化的结果

栅格标记板

创建栅格的标记板对象需要指定环境中每个标记的角位置。然而,在许多情况下,栅格标记板将只是同一平面和网格布局中的一组标记,因此可以轻松打印和使用,幸运的是,aruco模块提供了创建和打印这些类型标记的基本功能。

GridBoard类是一个专门的类,它继承了Board类,它表示一个板,其中包含同一平面和网格布局中的所有标记,如下图所示:

可以使用以下参数定义GridBoard对象:

  • X方向上的标记数。

  • Y方向上的标记数。

  • 标记侧的长度。

  • 标记物分隔的长度。

  • 标记物词典。

  • 所有标记的ID(X*Y标记)。

可以使用cv::aruco::GridBoard::create()静态函数从这些参数轻松创建此对象:

cv::aruco::GridBoard board = cv::aruco::GridBoard::create(5, 7, 0.04, 0.01, dictionary);
  • 第一和第二参数分别是X和Y方向上的标记物的个数。

  • 第三和第四个参数分别是标记长度和标记间距。它们可以以任何单位提供,记住该板的估计姿势将以相同单位测量(通常使用米)。

  • 最后给出了标记的字典。

因此,该板将由5x7=35个标记组成。默认情况下,从0开始按升序分配每个标记的ID,因此它们将是0、1、2、…、。这可以通过board.ids访问ids向量来轻松定制,就像在board父类中一样。

创建网格板之后,我们可能要打印并使用它。

cv::aruco::GridBoard::draw()

中提供了生成网格板图像的函数。例如

cv::aruco::GridBoard board = cv::aruco::GridBoard::create(5, 7, 0.04, 0.01, dictionary);
cv::Mat boardImage;
board.draw( cv::Size(600, 500), boardImage, 10, 1 );
  • 第一个参数是输出图像的像素大小。在这种情况下,600x500像素。如果这与标记板尺寸不成比例,则将以图像为中心。

  • boardImage:带板的输出图像。

  • 第三个参数是像素的(可选)边距,因此没有任何标记触及图像边界。

  • 最后,标记边框的大小,类似于drawMarker()函数,默认值为1。

输出图像如下所示:

创建标定板的完整工作示例包含在module samples文件夹中的create_board.cpp中。

标记检测的细化

如果我们检测到属于标定板的标记的子集,我们可以使用这些标记和标记板布局信息来尝试查找以前未检测到的标记。这可以使用refinedDetectedMarkers()函数来完成,该函数应该在调用detectMarkers()之后调用。此函数的主要参数是检测标记的原始图像、板对象、检测到的标记角点、检测到的标记ID和拒绝的标记角点。拒绝的角点可以从detectMarkers()函数获得,也被称为候选标记。这些候选者是在原始图像中发现的方形,但未能通过识别步骤(即其内部编码呈现太多错误),因此未被识别为标记。

然而,这些候选标记有时是由于图像中的高噪声、非常低的分辨率或其他影响二进制代码提取的相关问题而未被正确识别的实际标记。函数的作用是:

查找这些候选标记与标记板上丢失的标记之间的对应关系。此搜索基于两个参数:

候选标记与缺失标记的投影之间的距离:要获得这些投影,必须检测到标定板的至少一个标记,投影是使用相机参数(相机矩阵和失真系数)获得的,如果提供的话,如果不是,则从局部单应获得投影,并且只允许平面标记板(即所有标记角的Z坐标应相同),refinedDetectedMarkers()中的minRepDistance参数确定候选角点和投影标记角点之间的最小欧氏距离(默认值10)。

二进制编码:如果候选标记超过最小距离条件,则再次分析其内部位以确定它是否实际是投影标记,然而,在这种情况下,条件不是那么强,并且允许的错误比特的数目可以更高,这在errorCorrectionRate参数(默认值3.0)中表示,如果提供负值,则根本不分析内部位,只计算角距离。

这是使用finitedetectedmarkers()函数的示例:

 cv::aruco::Dictionary dictionary = cv::aruco::getPredefinedDictionary(cv::aruco::DICT_6X6_250);cv::aruco::GridBoard board = cv::aruco::GridBoard::create(5, 7, 0.04, 0.01, dictionary);vector< int > markerIds;vector< vector<Point2f> > markerCorners, rejectedCandidates;cv::aruco::detectMarkers(inputImage, dictionary, markerCorners, markerIds, cv::aruco::DetectorParameters(), rejectedCandidates);cv::aruco::refineDetectedMarkersinputImage, board, markerCorners, markerIds, rejectedCandidates);// After calling this function, if any new marker has been detected it will be removed from rejectedCandidates and included// at the end of markerCorners and markerIds

还必须注意的是,在某些情况下,如果首先检测到的标记数量太少(例如只有1或2个标记),丢失标记的投影质量可能很差,从而产生错误的对应。

资源

三维点云论文及相关应用分享

【点云论文速读】基于激光雷达的里程计及3D点云地图中的定位方法

3D目标检测:MV3D-Net

三维点云分割综述(上)

3D-MiniNet: 从点云中学习2D表示以实现快速有效的3D LIDAR语义分割(2020)

win下使用QT添加VTK插件实现点云可视化GUI

JSNet:3D点云的联合实例和语义分割

大场景三维点云的语义分割综述

PCL中outofcore模块---基于核外八叉树的大规模点云的显示

基于局部凹凸性进行目标分割

基于三维卷积神经网络的点云标记

点云的超体素(SuperVoxel)

基于超点图的大规模点云分割

更多文章可查看:点云学习历史文章大汇总

SLAM及AR相关分享

【开源方案共享】ORB-SLAM3开源啦!

【论文速读】AVP-SLAM:自动泊车系统中的语义SLAM

【点云论文速读】StructSLAM:结构化线特征SLAM

SLAM和AR综述

常用的3D深度相机

AR设备单目视觉惯导SLAM算法综述与评价

SLAM综述(4)激光与视觉融合SLAM

Kimera实时重建的语义SLAM系统

SLAM综述(3)-视觉与惯导,视觉与深度学习SLAM

易扩展的SLAM框架-OpenVSLAM

高翔:非结构化道路激光SLAM中的挑战

SLAM综述之Lidar SLAM

基于鱼眼相机的SLAM方法介绍

往期线上分享录播汇总

第一期B站录播之三维模型检索技术

第二期B站录播之深度学习在3D场景中的应用

第三期B站录播之CMake进阶学习

第四期B站录播之点云物体及六自由度姿态估计

第五期B站录播之点云深度学习语义分割拓展

第六期B站录播之Pointnetlk解读

[线上分享录播]点云配准概述及其在激光SLAM中的应用

[线上分享录播]cloudcompare插件开发

[线上分享录播]基于点云数据的 Mesh重建与处理

[线上分享录播]机器人力反馈遥操作技术及机器人视觉分享

[线上分享录播]地面点云配准与机载点云航带平差

如果你对本文感兴趣,请点击“原文阅读”获取知识星球二维码,务必按照“姓名+学校/公司+研究方向”备注加入免费知识星球,免费下载pdf文档,和更多热爱分享的小伙伴一起交流吧!

以上内容如有错误请留言评论,欢迎指正交流。如有侵权,请联系删除

扫描二维码

                   关注我们

让我们一起分享一起学习吧!期待有想法,乐于分享的小伙伴加入免费星球注入爱分享的新鲜活力。分享的主题包含但不限于三维视觉,点云,高精地图,自动驾驶,以及机器人等相关的领域。

分享及合作:群主微信“920177957”(需要按要求备注) 联系邮箱:dianyunpcl@163.com,欢迎企业来联系公众号展开合作。

点一下“在看”你会更好看耶

这篇关于opencv中ArUco模块实践(1)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!


原文地址:
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.chinasem.cn/article/1104757

相关文章

Spring Boot 配置文件之类型、加载顺序与最佳实践记录

《SpringBoot配置文件之类型、加载顺序与最佳实践记录》SpringBoot的配置文件是灵活且强大的工具,通过合理的配置管理,可以让应用开发和部署更加高效,无论是简单的属性配置,还是复杂... 目录Spring Boot 配置文件详解一、Spring Boot 配置文件类型1.1 applicatio

opencv图像处理之指纹验证的实现

《opencv图像处理之指纹验证的实现》本文主要介绍了opencv图像处理之指纹验证的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学... 目录一、简介二、具体案例实现1. 图像显示函数2. 指纹验证函数3. 主函数4、运行结果三、总结一、

tomcat多实例部署的项目实践

《tomcat多实例部署的项目实践》Tomcat多实例是指在一台设备上运行多个Tomcat服务,这些Tomcat相互独立,本文主要介绍了tomcat多实例部署的项目实践,具有一定的参考价值,感兴趣的可... 目录1.创建项目目录,测试文China编程件2js.创建实例的安装目录3.准备实例的配置文件4.编辑实例的

python+opencv处理颜色之将目标颜色转换实例代码

《python+opencv处理颜色之将目标颜色转换实例代码》OpenCV是一个的跨平台计算机视觉库,可以运行在Linux、Windows和MacOS操作系统上,:本文主要介绍python+ope... 目录下面是代码+ 效果 + 解释转HSV: 关于颜色总是要转HSV的掩膜再标注总结 目标:将红色的部分滤

Python 中的异步与同步深度解析(实践记录)

《Python中的异步与同步深度解析(实践记录)》在Python编程世界里,异步和同步的概念是理解程序执行流程和性能优化的关键,这篇文章将带你深入了解它们的差异,以及阻塞和非阻塞的特性,同时通过实际... 目录python中的异步与同步:深度解析与实践异步与同步的定义异步同步阻塞与非阻塞的概念阻塞非阻塞同步

Python Dash框架在数据可视化仪表板中的应用与实践记录

《PythonDash框架在数据可视化仪表板中的应用与实践记录》Python的PlotlyDash库提供了一种简便且强大的方式来构建和展示互动式数据仪表板,本篇文章将深入探讨如何使用Dash设计一... 目录python Dash框架在数据可视化仪表板中的应用与实践1. 什么是Plotly Dash?1.1

Python使用date模块进行日期处理的终极指南

《Python使用date模块进行日期处理的终极指南》在处理与时间相关的数据时,Python的date模块是开发者最趁手的工具之一,本文将用通俗的语言,结合真实案例,带您掌握date模块的六大核心功能... 目录引言一、date模块的核心功能1.1 日期表示1.2 日期计算1.3 日期比较二、六大常用方法详

springboot集成Deepseek4j的项目实践

《springboot集成Deepseek4j的项目实践》本文主要介绍了springboot集成Deepseek4j的项目实践,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价... 目录Deepseek4j快速开始Maven 依js赖基础配置基础使用示例1. 流式返回示例2. 进阶

Android App安装列表获取方法(实践方案)

《AndroidApp安装列表获取方法(实践方案)》文章介绍了Android11及以上版本获取应用列表的方案调整,包括权限配置、白名单配置和action配置三种方式,并提供了相应的Java和Kotl... 目录前言实现方案         方案概述一、 androidManifest 三种配置方式

Spring Boot中定时任务Cron表达式的终极指南最佳实践记录

《SpringBoot中定时任务Cron表达式的终极指南最佳实践记录》本文详细介绍了SpringBoot中定时任务的实现方法,特别是Cron表达式的使用技巧和高级用法,从基础语法到复杂场景,从快速启... 目录一、Cron表达式基础1.1 Cron表达式结构1.2 核心语法规则二、Spring Boot中定