论文阅读模块将分享点云处理,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)相关推荐

  1. OpenCV中GPU模块使用

    CUDA IT168的文章系列: Cuda的初始化 :http://tech.it168.com/a2011/0715/1218/000001218458.shtml OpenCV: OpenCV中G ...

  2. OpenCV中Viz模块的安装(VS2015)

    背景 因工作需要使用openCV中的Viz模块,而默认的OpenCV包是不含viz模块的.故需特别安装,现将安装过程简要记录如下,以作备忘. OpenCV 2.4.13 VTK 7.1.1 CMake ...

  3. OpenCV中OpenCL模块函数

    It currently develop and test on GPU devices only. This includes both discrete GPUs(NVidia,AMD), as ...

  4. OpenCV中检测ChArUco的角点(2)

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

  5. OpenCV_Viz——OpenCV中Viz的模块编译的无法解析的外部符号BUG

    写在前面 由于实验室需要,需要重新编译医学图像第三方库全家桶.这里就需要编译OpenCV,而编译后查看编译的库文件中缺少一个opencv_viz2413d.lib文件(没错,这里可以看出我使用的Ope ...

  6. 超详细!使用OpenCV深度学习模块在图像分类下的应用实践

    专注计算机视觉前沿资讯和技术干货 微信公众号:极市平台 官网:https://www.cvmart.net/ 极市导读:本文来自6月份出版的新书<OpenCV深度学习应用与性能优化实践>, ...

  7. [OpenCV实战]39 在OpenCV中使用ArUco标记的增强现实

    文章目录 1 什么是ArUco标记? 2 在OpenCV中生成ArUco标记 3 检测Aruco标记 4 增强现实应用 5 总结和代码 5.1 生成aruco标记 5.2 使用aruco增强现实 6 ...

  8. OpenCV进阶(10)在 OpenCV 中使用 ArUco 标记的增强现实

    在这篇文章中,我们将解释什么是 ArUco 标记,以及如何使用 OpenCV 将它们用于简单的增强现实任务. ArUco 标记已经在增强现实.相机姿态估计和相机校准中使用了一段时间.让我们更多地了解它 ...

  9. OpenCV Aruco模块常见问题解答

    OpenCV Aruco模块常见问题解答 Aruco模块常见问题解答 我只想标记一些对象,应该使用什么? 哪种算法用于标记检测? 无法正确检测我的标记,我该怎么办? ArUco板有什么好处?有什么缺点 ...

最新文章

  1. 留学计算机Ps模板,留学ps怎么写?出国留学ps模板
  2. python【力扣LeetCode算法题库】1111- 有效括号的嵌套深度
  3. 修改了n次效率还是不可接受
  4. 高斯坐标正反算c语言,高斯投影坐标正反算编程报告
  5. Go Iris 中间件
  6. 【双百解法】剑指 Offer 11. 旋转数组的最小数字
  7. 前端学习(3292):副作用
  8. 在谈数据治理和数字化的时候,别忘了数据标准
  9. python sorted下标_Python学习教程(Python学习路线):第七天-字符串和常用数据结构
  10. python dataframe函数_python pandas中DataFrame类型数据操作函数的方法
  11. CCIE-交换路由复习笔记
  12. 深入学习 Redis(1):Redis 内存模型
  13. java sql注入 过滤器_java 过滤器filter防sql注入 | 学步园
  14. Atitit.国际化中的日期与钱符号问题
  15. 气象数据之积温数据的获取与处理
  16. malicious java_[我研究] Detecting Malicious Java Code Using Virtual Machine Auditing
  17. 国内优秀的PHP商城系统整理
  18. axure中出现小手_Axure高保真滑动拼图解锁实例教程
  19. qt在表格中如何画线_在QtreeWidget中显示表格线,该如何处理
  20. 计算机机房的监控,机房动环监控解决方案

热门文章

  1. Appium 并发测试基于unitest
  2. 在Ubuntu18.04上安装opencv 3.4.1
  3. Java基础(二十七)Java IO(4)字符流(Character Stream)
  4. 数据库Mysql的学习(八)-储存过程和事务和导入导出
  5. 2022-2028年中国食品电商行业投资分析及前景预测报告
  6. 机器学习入门(05)— 使用 NumPy 实现 3 层简单神经网络
  7. MySQL 修改账号的IP限制条件
  8. 传智168期JavaEE struts2杜宏 day 29~day31笔记(2017年2月4日23:14:00)
  9. 友盟页面统计 - 关于Viewpager中的Fragment的生命周期
  10. 用TCP/IP进行网际互联一