OpenCV4学习笔记(72)——ArUco模块之aruco标记的创建与检测

2023-05-16

今天要整理记录的是OpenCV中ArUco模块的基础内容,包含aruco标记的创建与检测。要注意的是ArUco模块是包含在OpenCV的contrib拓展库中的,需要自行下载OpenCV基础库和contrib拓展库进行联合编译才可以使用,这里就不整理编译的过程了,不得不说编译的时候还是有好多坑的。。。如果有需要的朋友可以在我的资源里面下载 “OpenCV430(contrib).txt”,这是编译好了的包含contrib拓展库的OpenCV4.3.0版本,由于文件过大所以使用的是某度网盘链接的方式上传,介意下载速度的朋友就还是别下载了。把压缩包下载解压后再进行环境配置,就可以直接使用OpenCV中拓展库的内容了,顺带一提,编译的时候我选择的是AVX2指令集,相比起OpenCV默认的SSE3指令集有一定程度的优化,当然了这个需要个人的电脑CPU支持才可以,所以下载的朋友需要注意一下。

言归正传,下面先来了解一下什么是aruco标记:
aruco标记是可用于摄像机姿态估计的二进制方形基准标记。它的主要优点是检测简单、快速,并且具有很强的鲁棒性。ArUco 标记是由宽黑色边框和确定其标识符(id)的内部二进制矩阵组成的正方形标记。aruco标记的黑色边框有助于其在图像中的快速检测,内部二进制编码用于识别标记和提供错误检测和纠正。aruco标记尺寸的大小决定内部矩阵的大小,例如尺寸为 4x4 的标记由 16 位二进制数组成。

通俗地说,aruco标记其实就是一种编码,就和我们日常生活中的二维码是相似的,只不过由于编码方式的不同,导致它们存储信息的方式、容量等等有所差异,所以在应用层次上也会有所不同。由于单个aruco标记就可以提供足够的对应关系,例如有四个明显的角点及内部的二进制编码,所以aruco标记被广泛用来增加从二维世界映射到三维世界时的信息量,便于发现二维世界与三维世界之间的投影关系,从而实现姿态估计、相机矫正等等应用。

OpenCV中的ArUco模块包括了对aruco标记的创建和检测,以及将aruco标记用于姿势估计和相机矫正等应用的相关API,同时还提供了标记板等等。本次笔记中主要先整理aruco标记的创建与检测。

首先我们创建aruco标记时,需要先指定一个字典,这个字典表示的是创建出来的aruco标记具有怎样的尺寸、怎样的编码等等内容,我们使用APIgetPredefinedDictionary()来声明我们使用的字典。在OpenCV中,提供了多种预定义字典,我们可以通过PREDEFINED_DICTIONARY_NAME来查看有哪些预定义字典。而且字典名称表示了该字典的aruco标记数量和尺寸,例如DICT_7X7_50表示一个包含了50种7x7位标记的字典。

确定好我们需要的字典后,就可以通过APIdrawMarker()来绘制出aruco标记,其参数含义如下:
(1)参数dictionary: 之前创建的 Dictionary 对象指针
(2)参数id:标记 id,表示绘制字典中的哪一个aruco标记。每个字典由不同数量的标记组成,id 有效范围是 [ 0,字典包含的标记数 ),任何超出有效范围的特定 id 都会产生异常。
(3)参数 sidepixel: 输出标记图像的尺寸,输出标记图像的尺寸为Size(sidepixel,sidepixel);此参数应足够大以存储特定字典的位数,至少需要满足(sidepixel - 标记的边长)>= 2;
并且为了避免输出标记图像变形,sidepixel应与位数 + 边界大小成比例,或者至少比标记尺寸大得多,以使变形不明显。
(4)参数img:输出的标记图像;
(5)参数borderBist:用于指定标记黑色边框的宽度,例如borderBist=2 表示边框的宽度等于两个内部像素的大小,默认值 borderBist= 1。

这样,我们就创建了一个选定字典的aruco标记了,下面我们创建5个不同的aruco标记来对比下,演示代码如下:

	//创建aruco标记
	Mat marker;
	auto dictionary = aruco::getPredefinedDictionary(aruco::PREDEFINED_DICTIONARY_NAME::DICT_6X6_250);
	for (int i = 0;i < 5;i++)
	{
		aruco::drawMarker(dictionary, i, 200, marker, 1);
		string windowName = "marker" + to_string(i);
		imshow(windowName, marker);
		string path ="D:\\"+ windowName + ".jpg";
		imwrite(path, marker);
	}

创建的aruco标记如下:
在这里插入图片描述

接下来,当我们把aruco标记打印出来后贴在任意其它地方后,再进行拍摄,就可以对aruco标记进行检测。检测aruco标记的API是detectMarkers(),其参数含义如下:
(1)参数image:输入的需要检测标记的图像;
(2)参数dictionary:进行检测的字典对象指针,这里的字典就是我们创建aruco标记时所使用的字典,检测什么类型的aruco标记就使用什么类型的字典;
(3)参数corners:检测到的aruco标记的角点列表,对于每个标记,其四个角点均按其原始顺序返回(从右上角开始顺时针旋转),第一个角是右上角,然后是右下角,左下角和左上角。
注意这里的返回角点顺序,在OpenCV官方文档中记录的是从左上角开始进行旋转,而经过我的测试,发现是以右上角为起点的,这应该是官方文档中的笔误,而且官方文档中关于contrib拓展库部分的内容可能由于更新频率低,其中还存在着不少小问题,朋友们在看的时候要注意自己检验一下里面的内容,千万不用拿来即用,很可能掉坑。
(4)参数ids:检测到的每个标记的 id,需要注意的是第三个参数和第四个参数具有相同的大小;
(5)参数parameters: DetectionParameters 类的对象,该对象包括在检测过程中可以自定义的所有参数;
(6)参数rejectedImgPoints:抛弃的候选标记列表,即检测到的、但未提供有效编码的正方形。每个候选标记也由其四个角定义,其格式与第三个参数相同,该参数若无特殊要求可以省略。

当我们进行aruco标记检测后,为了方便我们观察,通常需要进行可视化操作,也就是把检测到的aruco标记绘制出来,我们使用drawDetectedMarkers()这个API来绘制检测到的aruco标记,其参数含义如下:
(1)参数image: 是将绘制标记的输入 / 输出图像(通常就是检测到标记的图像)
(2)参数corners:检测到的aruco标记的角点列表
(3)参数ids:检测到的每个标记对应到其所属字典中的id
(4)参数borderColor:绘制标记外框的颜色

对aruco标记进行检测并绘制的演示代码如下:

		auto dictionary = aruco::getPredefinedDictionary(aruco::PREDEFINED_DICTIONARY_NAME::DICT_6X6_250);
		vector<vector<Point2f>>corners, rejectedImgPoints;
		vector<int>ids;
		auto parameters = aruco::DetectorParameters::create();
		aruco::detectMarkers(test_image, dictionary, corners, ids, parameters, rejectedImgPoints);
		aruco::drawDetectedMarkers(test_image, corners, ids, Scalar(0, 255, 0));

效果如下:

在这里插入图片描述
放大观察:
在这里插入图片描述
在这里插入图片描述
可以看到每个aruco标记的边框上,都有一个绿色矩形框,而在标记的中心,有一个id值,这个id就是该标记在其所属字典中的id。

那么到这里,我们就完成了对aruco标记的创建和检测工作,这是一个基础操作,后续的姿态估计、相机标定等等操作都是建立在此基础之上的。本次笔记就先到此为止,下次再来整理一下对aruco标记进行实时姿态估计的相关内容。

PS:本人的注释比较杂,既有自己的心得体会也有网上查阅资料时摘抄下的知识内容,所以如有雷同,纯属我向前辈学习的致敬,如果有前辈觉得我的笔记内容侵犯了您的知识产权,请和我联系,我会将涉及到的博文内容删除,谢谢!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

OpenCV4学习笔记(72)——ArUco模块之aruco标记的创建与检测 的相关文章

  • Java-gradle编译忽略警告

    使用gradle打包的时候出现好多警告 如何忽略大部分的警告呢 使用如下配置即可 tasks span class token punctuation span span class token function withType span
  • JPA-排除实体类里不存在于数据库的字段

    在实体类与数据库表建立映射关系时添加 64 Table 注解 当表中不存在实体类中的某个属性的时候 就需要用到 64 Transient 注解 如果不好使那么在 64 Transient基础上在添加 64 Column updatable
  • SpringBoot-快速搭建一套JPA

    文章目录 结构Mavenapplication yml实体类daoservicecontroller测试 结构 Maven span class token tag span class token tag span class token
  • IntelliJ IDEA-Gradle-SpringBoot搭建

    前提条件 IntelliJ IDEA Gradle教学 Gradle 全局镜像配置和优先使用Maven 将Gradle进行安装和配置 创建项目 配置项目设置 指定自己的gradle的安装位置 以及仓库位置 用户主目录 用户主目录 Gradl
  • 我的喜马拉雅FM开播啦!

  • SpringBoot-JAP-JpaSpecificationExecutor详解

    文章目录 SpringBoot JAP JpaSpecificationExecutor详解使用方法接口介绍自定义工厂 SpringBoot JAP JpaSpecificationExecutor详解 JpaSpecificationEx
  • SwitchHosts-快速切换Hosts

    SwitchHosts是一个管理 快速切换Hosts小工具 xff0c 开源软件 xff0c 一键切换Hosts配置 xff0c 非常实用 xff0c 高效 其主要功能特性包括 xff1a 下载地址 https github com old
  • Java-新年抽奖-消息自动化发送脚本

    我们公司7点半开年会 然后大约8点半开始抽奖抢 使用腾讯会议的方式进行发关键字消息然后截图方式抽奖 然而我还在地铁上 手速慢的我只抽到了3等奖小米耳机一个 然后我回家后迫不及待第一时间赶紧使用java写一个机器人脚本 疯狂发消息 一言难尽啊
  • Java多线程-CompletableFuture(链式)

    线程池这个大家都知道 xff0c 是为了提高效率 xff0c 可以类比生活 xff0c 如果开个店 xff0c 需要几个员工 xff0c 正常的操作都是雇佣员工 xff0c 而不是每天使用临时工 xff0c 这样用完就解雇掉 xff0c 对
  • Java-Javassist(字节码修改)

    文章目录 开篇Javassist 常用类Javassist 的使用依赖代码示例 如何实现类似 AOP 的功能 开篇 说起 AOP 小伙伴们肯定很熟悉 xff0c 无论是 JDK 动态代理或者是 CGLIB 等 xff0c 其底层都是通过操作
  • Java多线程-Pip管道

    管道的意思 就是向一个管子一样从一端到另一端 只支持单方向的数据传输 需要注意的不能在同一个线程使用管道否则会导致死锁的情况 发生和接收必须在不同线程 通过使用管道 xff0c 实现不同线程间的通信 xff0c 而无需借助于临时文件之类的东
  • 新版本代码自动生成(MybatisPlus-generator) 代码示例+问题解决

    虽然MybatisPlus官网上已经给出了新版本代码生成器的核心依赖和核心代码 xff0c 但对于没接触过的小伙伴还是比较困难上手 x1f62d xff0c 本文将展现如何使用MybatisPlus generator快速生成代码 目录 1
  • 虚拟机如何使用共享文件夹传文件

    项目场景 xff1a 在使用VMware平台 xff0c ubuntu操作系统时 xff0c ftp文件传输一直报错 问题描述 xff1a 尝试了多种 xff0c 更改电脑设置 xff0c 甚至重装虚拟机 xff0c 始终如下图报错 解决方
  • 强化学习入门DQN详解

    Deep Q Network 参考资料 xff1a B站莫烦 xff1a https www bilibili com video BV13W411Y75P spm id from 61 333 337 search card all cl
  • 某项目因为多次流标导致实际项目时间严重压缩,我该咋办?

    问题 xff1a 某政府项目 xff0c 三个月前就开始招标 xff0c 因各种原因 xff0c 流标三次 xff0c 导致时间拖太长 原计划一期工期三个月 43 xff0c 1月底上线 xff0c 但因为招投标影响直到一个月前签订了合同
  • ROS创建工作空间及功能包流程总结整理(python)

    ROS创建工作空间及功能包流程总结整理 xff08 python xff09 参考资料 xff1a B站赵虚左 xff1a https www bilibili com video BV1Ci4y1L7ZZ p 61 19 amp vd s
  • ROS自定义发布消息类型

    ROS自定义发布消息类型 xff1a 在 ROS 通信协议中 xff0c 数据载体是一个较为重要组成部分 xff0c 在上一案例中 xff0c ROS 中通过 std msgs 封装了一些原生的数据类型 比如 String Int32 In
  • ROS服务通信:自定义数据文件以及服务端和客户端代码编写流程及步骤详解

    ROS服务通信具体实现流程 demo xff1a 实现两个整型数相加求和 xff0c 客户端发送两个整型数 xff0c 服务端对其求和 服务通信也需要自定义服务数据类型 xff0c 即自定义srv文件 xff0c 该过程和自定义msg文件非
  • ROS TF静态坐标变换实现

    ROS TF静态坐标变换实现 法一 xff1a 编码实现 发布方代码实现 xff1a 创建功能包并添加依赖 catkin create pkg tf static roscpp rospy std msgs tf2 tf2 ros tf2
  • ROS:Gazebo导入自定义环境

    Gazebo导入自定义环境 之前的案例gazebo中导入的是一个空世界empty world xff0c 这里会介绍如何导入房屋数目等自定义的环境 xff08 1 xff09 启动 gazebo 打开构建面板 xff0c 绘制仿真环境 xf

随机推荐

  • ROS导航实现:SLAM建图(slam_gmapping)与保存(map_server)

    导航实现 xff1a SLAM建图 先安装相关的ROS功能包 安装 gmapping 包 用于构建地图 sudo apt install ros lt ROS版本 gt gmapping 安装地图服务包 用于保存与读取地图 sudo apt
  • ROS导航实现:amcl定位

    ROS导航实现 xff1a amcl定位 xff08 1 xff09 首先编写启动amcl的launch文件 xff0c 这里建议复制粘贴模板 xff0c 再修改相关的参数即可 xff0c 步骤如下 xff1a 主目录下进入amcl文件 r
  • ROS导航实现之路径规划

    导航实现之路径规划 move base 功能包提供了基于动作 action 的路径规划实现 xff0c move base 可以根据给定的目标点 xff0c 控制机器人底盘运动至目标位置 xff0c 并且在运动过程中会连续反馈机器人自身的姿
  • 创建个人网站(github pages)并将站点一键托管到Github

    创建个人网站 xff08 github pages xff09 并将站点一键托管到Github 内容 xff1a 使用网站生成器mkdocs将markdown文件生成wiki站点并挂载到github的流程总结 亮点 xff1a 个人网站一键
  • 视觉SLAM十四讲(第2版)总结

    最近看完了 视觉SLAM十四讲 xff08 第2版 xff09 xff1a 从理论到实践 xff08 高翔等著 xff09 xff0c 原书分两部分 xff0c 先介绍了数学基础 xff0c 然后介绍了具体的SLAM实践 xff0c 非常适
  • 我的公众号 - 豆芽儿 软件研发人才生长社区

    为你系统分享敏捷开发 项目管理 需求分析 软件设计 UML 中层领导力 CMMI IT职场 ACP 软考 PMP等 高大上 的实用知识 xff0c 帮助你进阶为高端人才 xff01
  • Openblas 下载和使用方法

    Openblas 下载及使用 环境 xff1a 平台 xff1a Ubuntu 20 04 xff0c Orin xff1a Arm Cortex A78AE v8 2 64 bit 步骤 xff1a 1 去github 下载openbla
  • FreeRTOS学习记录

    FreeRTOS学习记录 前言FreeRTOS学习记录在STM32CubeMX中配置FreeRTOS 前言 本人小白 xff0c 最近学习了FreeRTOS操作系统 xff0c 打算做一点记录 学习的过程中虽然做了点练习 xff0c 不过都
  • 如何给华三交换机恢复出厂设置及命令

    如何给华三交换机恢复出厂设置及命令 在前几天 xff0c 上级单位线路重新规划 xff0c 需要我们将单位的线路进行改造 xff0c 这就涉及到了网络设备的重新配置 经查看 xff0c 上级接入交换机的业务端口配置为access xff0c
  • 解决Linux下Docker下载安装太慢

    卸载先前版本 yum remove docker docker span class token operator span client docker span class token operator span client span
  • sqlyong连接docker中的mysql 失败can‘t connect to MySQL server on (*******:3306)

    解决sqlyong连接docker中myslq失败 xff1a 一 查看mysql是否运行docker ps 二 查看mysql端口映射是否与连接相符 三 进入mysql容器查看是否能够进行本地连接docker exec it mysql
  • 解决springboot+webSocket出现404错误

    这是因为websocket创建的bean是由自己来管理的 需要将其创建的bean交给spring管理 创建websocketconfig span class token keyword package span com span clas
  • Bytebuffer源码剖析及实现原理

    Bytebuffer 官方解释A byte buffer xff0c 一个字节缓冲区 一 使用方法 ByteBuffer 初始状态是写模式 使用IO流即可写入数据 如 channel read 如果需要读取ByteBuffer中的数据调用f
  • Linux下安装并配置FTP文件服务器

    一 安装vsftpd 1 运行如下代码安装vsftpd yum install span class token operator span y vsftpd 2 运行以下命令设置FTP服务开机自启动 systemctl enable vs
  • Java 实现 图片OCR文字识别

    Java 实现图片OCR文字识别功能 前言 由于网上很多算法 以及语言库无法做到精准识别 所以综合条件下 使用了一款 space OCR API 的产品进行使用 每个月有25000条的 使用额度 日常使用或开发绰绰有余 网址链接 一 注册
  • js实现表单的校验

    js实现表单校验 CV即用 1 效果图 当每个输入框失去焦点时会通过正则表达式来验证输入的格式是否正确 点击登录按钮后 xff0c 如果有格式不正确的将无法登录 当校验全部通过以后才可以登录 2 源代码 xff1a HTML代码 xff1a
  • 你和国际项目经理(PMP),一步之遥?-张传波-专题视频课程

    你和国际项目经理 PMP xff0c 一步之遥 xff1f 913人已学习 课程介绍 项目管理是门实战性超强的大学问 xff0c 项目经理是一位能把控全局的 狠 角色 xff01 你距离这样的 狠 角色有多远呢 xff0c 你应该如何规划自
  • RTOS任务切换原理与实现

    曾今只是使用过移植好的RTOS进行任务开发 xff0c 对其实现的底层原理一直一知半解 xff0c 正好接触到了李述桐老师的课程以及一些网上的资料 xff0c 让我对实时操作系统的原理有了更深的理解 xff0c 特此把一些原理和思考记录下来
  • python报错:Process finished with exit code -1066598274 (0xC06D007E) 解决方法

    1 在运行Mask RCNN项目时 xff0c 导入官网下载的代码和数据集 xff0c 准备运行时报此错误 2 原因 官网要求python版本是3 4 xff0c 但是我python编译器版本为3 9 3 解决 将编译器版本更换为3 7试试
  • OpenCV4学习笔记(72)——ArUco模块之aruco标记的创建与检测

    今天要整理记录的是OpenCV中ArUco模块的基础内容 xff0c 包含aruco标记的创建与检测 要注意的是ArUco模块是包含在OpenCV的contrib拓展库中的 xff0c 需要自行下载OpenCV基础库和contrib拓展库进