ArUco

2023-05-16

文章目录

  • 一、ArUco简介
  • 二、Marker和字典
  • 三、步骤
    • 1.创建Marker(Marker Creation)
    • 2.检测Marker(Marker Detection)
    • 3.姿态估计(Pose Estimation)

一、ArUco简介

  姿态估计(Pose estimation)在计算机视觉领域扮演着十分重要的角色:如机器人导航、目标跟踪和相机定标等。所谓姿态估计问题就是要确定某个三维物体的方位指向问题,也就是确定以该物体为中心原点的一个坐标系。这一过程的基础是找到现实世界和图像投影之间的对应点。这通常是困难的,因此我们使用Marker解决这一问题。
  aruco模块基于ArUco库,这是一个检测二进制marker的非常流行的库。
  aruco标记其实就是一种编码,就和我们日常生活中的二维码是相似的,只不过由于编码方式的不同,导致它们存储信息的方式、容量等等有所差异。由于单个aruco标记就可以提供足够的对应关系,例如有四个明显的角点及内部的二进制编码,所以aruco标记被广泛用来增加从二维世界映射到三维世界时的信息量,便于发现二维世界与三维世界之间的投影关系,从而实现姿态估计、相机矫正等等应用。

aruco的函数包含在#include <opencv2/aruco.hpp>,该库主要的类主要有:
aruco::Marker----视觉标志类;
aruco::MarkerDetector----视觉标志检测类;
aruco::MarkerPoseTracker----视觉标志姿态预估类;
aruco::MarkerMap-----视觉标志地图类;
aruco::MarkerMapPoseTracker----视觉标志地图姿态预估类;
aruco::CvDrawingUtils----绘图类;

二、Marker和字典

  ArUco marker是一个由二进制矩阵组成的正方形标记。它由一个宽黑色边框和一个内部的二进制矩阵组成。黑色边框有利于快速检测到图像,内部二进制编码用于识别标记和提供错误检测和纠正。marker的尺寸的大小决定了内部矩阵的大小。例如,一个4x4的marker由16 位二进制数(16bits)组成。
  
一些marker图像示例:
在这里插入图片描述

  应当注意到,我们需要检测到一个Marker在空间中发生了旋转,但是,检测的过程需要确定它的初始角度,所以每个角落需要是明确的,不能有歧义,保证上述这点也是靠二进制编码完成的。
  markers的字典是在一个特殊应用中使用到的marker的集合。这仅仅是每个marker的二进制编码的链表。
  字典的主要性质是字典的大小marker的大小:字典的大小是组成字典的marker的数量;marker的大小是这些marker的尺寸(位的个数)。
  aruco模块包含了一些预定义的字典,这些字典涵盖了一系列的字典大小和Marker尺寸。
  一个marker的 id 仅是marker在它所在的字典的下标,由内部的矩阵决定。例如,一个字典里的五个marker的 id 是:0,1,2,3 和 4。

三、步骤

1.创建Marker(Marker Creation)

cv::Mat markerImage; 
cv::aruco::Dictionary dictionary = cv::aruco::getPredefinedDictionary(cv::aruco::DICT_6X6_250); 
cv::aruco::drawMarker(dictionary, 23, 200, markerImage, 1);

getPredefinedDictionary():
  在我们创建aruco标记之前,需要先指定一个字典。这个字典表示的是创建出来的aruco标记具有怎样的尺寸、怎样的编码等等内容。我们使用这个API来声明我们使用的字典。在OpenCV中,提供了多种预定义字典,我们可以通过PREDEFINED_DICTIONARY_NAME来查看有哪些预定义字典。而且字典名称表示了该字典的aruco标记数量和尺寸,例如DICT_6X6_250表示一个包含了250种6x6位标记的字典。
  
drawMarker()
  确定好我们需要的字典后,就可以通过这个API来生成aruco标记,其参数含义如下:
(1)参数dictionary: 之前创建的 Dictionary 对象;
(2)参数id:marker 的 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);
	}

  效果如下:
在这里插入图片描述

2.检测Marker(Marker Detection)

cv::Mat inputImage; 
vector< int > markerIds;
vector< vector<Point2f> > markerCorners, rejectedCandidates;
cv::aruco::DetectorParameters parameters; 
cv::aruco::Dictionary dictionary = cv::aruco::getPredefinedDictionary(cv::aruco::DICT_6X6_250); 
cv::aruco::detectMarkers(inputImage, dictionary, markerCorners, markerIds, parameters, rejectedCandidates);

detectMarkers()
  当我们把aruco标记打印出来后贴在任意其它地方后,再进行拍摄,就可以对aruco标记进行检测。这个API用于检测aruco标记,其参数含义如下:
(1)参数image:输入的需要检测标记的图像;
(2)参数dictionary:进行检测的字典对象,这里的字典就是我们创建aruco标记时所使用的字典,检测什么类型的aruco标记就使用什么类型的字典;
(3)参数corners:检测到的aruco标记的角点列表,对于每个标记,其四个角点均按其原始顺序返回(从右上角开始顺时针旋转),第一个角是右上角,然后是右下角,左下角和左上角;

注意这里的返回角点顺序,在OpenCV官方文档中记录的是从左上角开始进行旋转,而经过测试,发现是以右上角为起点的。
(4)检测到的每个标记的 id,需要注意的是第三个参数和第四个参数具有相同的大小;
(5)参数parameters: DetectionParameters 类的对象,该对象包括在检测过程中可以自定义的所有参数;
(6)参数rejectedImgPoints:抛弃的候选标记列表,即检测到的、但未提供有效编码的正方形。每个候选标记也由其四个角定义,其格式与第三个参数相同,该参数若无特殊要求可以省略。
  
drawDetectedMarkers():
  当我们进行aruco标记检测后,为了方便我们观察,通常需要进行可视化操作,也就是把检测到的aruco标记绘制出来,我们使用这个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标记的创建和检测。后续的姿态估计、相机标定等等操作都是建立在此基础之上的。

3.姿态估计(Pose Estimation)

Mat cameraMatrix, distCoeffs;  
vector< Vec3d > rvecs, tvecs; 
cv::aruco::estimatePoseSingleMarkers(corners, 0.05, cameraMatrix, distCoeffs, rvecs, tvecs);

  接下来要通过Marker检测来获取相机pose。
  为了获取相机pose,需要知道相机的校准(Calibration)参数,即相机矩阵和畸变系数。
  注:当用ArUco marker来检测相机Pose时,可以单独地检测每个Marker的pose。如果想要从一堆Marker里检测出一个pose,需要的是aruco板。(参见ArUco板教程)
  涉及到marker的相机pose是一个从marker坐标系统到相机坐标系统的三维变换。这是由一个旋转和一个平移向量确定的(参见 solvePnP() 函数)。

  当我们每检测到一个aruco标记,vector<vector<Point2f>>corners中就会获得一个检测到标记的角点列表,我们接下来就通过这个角点列表来对该标记进行姿态估计。
  
estimatePoseSingleMarkers()
  OpenCV中提供了这个API来实现对这种简单标记的姿态估计,其参数含义如下:
(1)参数corners: detectMarkers()返回的检测到标记的角点列表,是一个vector<vector<Point2f>>类型的元素;
(2)参数markerLength:aruco标记的实际物理尺寸,也就是我们打印出来的aruco标记的实际尺寸,一般以米为单位;
(3)参数cameraMatrix:相机的内参矩阵;
(4)参数distCoeffs:相机的畸变参数;
(5)参数rvecs:vector<cv::Vec3d>类型的向量,其中每个元素为每个标记相对于相机的旋转向量;
(6)参数tvecs:vector<cv::Vec3d>类型的向量,其中每个元素为每个标记相对于相机的平移向量。
(7)参数_objPoints:每个标记角点的对应点数组。
  
  接收 detectMarkers()检测到的aruco标记(以输出角点列表的方式表示),并分别对每个标记进行姿态估计。因此,每个aruco标记都将返回一个相对于相机的旋转向量和平移矢量,返回的点数组是将标记角点从每个标记坐标系转换到相机坐标系下的表示。
  标记坐标系原点位于标记的中心,Z轴垂直于标记平面,每个标记的四个角点在其坐标系中的坐标为:(-markerLength / 2,markerLength / 2,0)(markerLength / 2,markerLength / 2,0)(markerLength / 2,-markerLength / 2 ,0)(-markerLength / 2,-markerLength / 2,0),其中,markerLength是aruco标记的边长。
  
  通过这个API,我们就能实现对简单aruco标记的姿态估计了,但是我们还需要把它进行可视化来便于我们查看,所以我们可以绘制出每个aruco标记的坐标轴,从而查看姿态估计的结果。
  
drawAxis()
  我们使用这个API来绘制坐标轴,其参数含义为:
(1)参数image:绘制坐标轴的输入、输出图像(通常是进行检测标记的图像);
(2)参数cameraMatrix:相机的内参矩阵;
(3)参数distCoeffs:相机的畸变参数;
(4)~(5)参数rvec和参数tvec:当前要绘制坐标轴的物体的姿态参数,分别是旋转向量和平移向量;
(6)参数length:绘制坐标轴的长度,单位通常为米。

  我们需要加载相机的内参矩阵和畸变系数,这里是默认标定好了的,直接获取的参数,演示代码如下:

cv::Mat cameraMatrix, distCoeffs;
vector<double> camera = { 657.1548323619423, 0, 291.8582472145741,0, 647.384819351103, 391.254810476919,0, 0, 1 };
cameraMatrix = Mat(camera);
cameraMatrix = cameraMatrix.reshape(1,3);
vector<double> dist = { 0.1961793476399528, -1.38146317350581, -0.002301820186177369, -0.001054637905895881, 2.458286937422959 };
distCoeffs = Mat(dist);
distCoeffs = distCoeffs.reshape(1, 1);

  然后,调用摄像头

VideoCapture capture;
capture.open(0);
if (!capture.isOpened())
{
	cout << "can't open camera" << endl;
	exit(-1);
}

  接着在每一帧图像中都进行aruco标记的检测以及姿态估计,并绘制出每一帧中检测到的aruco标记的坐标轴

Mat frame;
while (capture.read(frame))
{
	Mat test_image;
	resize(frame, test_image, Size(800, 800));
	imshow("test_image", test_image);
	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));
	//namedWindow("dectect", WINDOW_FREERATIO);
	//imshow("dectect", test_image);

	std::vector<cv::Vec3d> rvecs;
	std::vector<cv::Vec3d> tvecs;
	cv::aruco::estimatePoseSingleMarkers(corners, 0.053, cameraMatrix, distCoeffs, rvecs, tvecs);
	for (int i = 0;i < rvecs.size();i++)
	{
		//绘制坐标轴,检查姿态估计结果
		cv::aruco::drawAxis(test_image, cameraMatrix, distCoeffs, rvecs[i], tvecs[i], 0.02);
	}
	//namedWindow("pose", WINDOW_FREERATIO);
	imshow("pose", test_image);

	char ch = cv::waitKey(1);
	if (27 == ch)
	{
		break;
	}
}


  下面是效果演示:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

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

ArUco 的相关文章

  • ArUco----一个微型现实增强库的介绍及视觉应用(二)

    很重要的一点就是这个 转载自 xff1a https www cnblogs com shawn0102 p 8039439 html ArUco 一个微型现实增强库的介绍及视觉应用 xff08 二 xff09 ArUco 一个微型现实增强
  • python下使用aruco标记进进行三维姿势估计(转载)

    转载自 xff1a https www it610 com article 1291934151255072768 htm python下使用aruco标记进进行三维姿势估计 视觉机器人 python3 aruco python openc
  • 基于opencv的ArUco的视觉定位之ArUco安装

    小编之前在前面的文章里是通过安装opencv 43 contirb来实现使用aruco xff0c 但在进行aruco的源码学习时 xff0c 发现不少类contirb里库是没有的 xff0c 于是不得不再装一个独立的aruco的库 xff
  • OpenCV基础(19)使用 OpenCV 和 Python 检测 ArUco 标记

    在本教程中 xff0c 您将学习如何使用 OpenCV 和 Python 检测图像和实时视频流中的 ArUco 标记 1 使用 OpenCV 和 Python 检测 ArUco 标记 在本教程的第一部分 xff0c 您将了解 OpenCV
  • ArUco标定板生成与打印

    链接如下 xff1a https span class token punctuation span span class token operator span chev span class token punctuation span
  • 【OpenCV】ArUco Marker

    1 创建 span class token keyword import span cv2 span class token keyword as span cv span class token keyword import span n
  • 基于ArUco的视觉定位(三)

    一 ArUco之Marker Mapper 1 Marker Mapper简介 Mapping and Localization from Planar Markers是A V A小组基于ArUco开发的一个利用二维码建图与定位的项目 论文
  • 二维相机能得到三维信息?机器人感知部分之Aruco标定板的使用

    大家好 xff0c 我是小鱼 xff0c 今天来介绍一下Aruco并是结合ROS来进行识别 aruco其实是opencv中的一个库 xff0c 可以将特定的标记物转换成三维的坐标 xff0c 所以它是可以脱离ROS进行使用的 aruco介绍
  • opencv_contrib aruco源码

    https github com opencv opencv contrib tree master modules 最近使用了aruco模块 想看看aruco的源码是怎样实现的 在opencv源码中一直没找到aruco 原来 他隐藏在op
  • aruco marker 的使用

    安装aruco 教程 xff1a make make install
  • aruco安装 配合realsense 使用

    使用github安装 网址 xff1a http www uco es investiga grupos ava node 26 git clone到本地之后 xff0c catkin make即可开始使用 使用apt安装 span cla
  • opencv_aruco

    文章参考 xff1a ArUco 木筏筏筏的博客 CSDN博客 aruco 1 01 显示识别mark cpp include lt opencv2 highgui hpp gt include lt opencv2 aruco hpp g
  • 源码实现 Aruco检测

    以下为实现aruco检测并读取id的代码 xff0c 直接复制粘贴即可 相信看到这篇博客的伙伴应该知道aruco xff0c 我就不解释了 opencv3 0以上有实现aruco的库 一 cmake编译信息 Cmakelist txt cm
  • ArUco----一个微型现实增强库的介绍及视觉应用(二)

    ArUco 一个微型现实增强库的介绍及视觉应用 xff08 二 xff09 ArUco 一个微型现实增强库的介绍及视觉应用 xff08 二 xff09 一 第一个ArUco的视觉应用 首先介绍第一个视觉应用的Demo xff0c 这个应用场
  • aruco marker使用笔记

    在英伟达Jetson Xaiver开发板上配置 SDK环境 opencv 4 1 1 CUDA 10 2 1 git clone https github com pal robotics aruco ros 2 复制到catkin ws
  • 【AR】使用OpenCV中的aruco模块实现增强现实

    1 ArUco marker ArUco marker是由S Garrido Jurado等人在2014年提出的 xff0c 全称是Augmented Reality University of Cordoba xff0c 详见他们的论文
  • aruco二维码

    1 二维码的生成 简单方式 xff1a 直接在下面的网站上选择 xff0c 操作简单https chev me arucogen 网站界面如下 xff1a
  • Opencv Aruco识别(python)

    效果图 先上效果 代码 直接上代码 xff1a span class token operator span span class token operator span usr span class token operator span
  • 在 openCV 中的特定坐标处将图像显示在另一图像上

    我试图在特定坐标处将一个图像显示在另一个图像上 我已使用网络摄像头检测到 aruco 标记 并且我想在 aruco 标记上显示另一个图像 aruco 标记可以移动 并且覆盖的图像应与标记一起移动 有各种绘图功能并将文本输入到图像中 我尝试过
  • ArUco 位姿估计中的不稳定值

    我正在尝试使用 Aruco 标记找到相机的方向 从旋转矩阵中提取的欧拉角在超过某一点时不稳定 随着相机与标记的距离增加 相机的偏航角值不稳定 标记上的 Z 轴翻转 欧拉角不稳定 每帧都不相同 需要时间才能稳定 如何获得相机和标记之间的偏航角

随机推荐

  • 2018年4月最新版虚拟机(包含APM开发环境和PX4开发环境)

    以下为 2018年4月最新版代码编译 的虚拟机 xff08 包含APM开发环境和PX4开发环境 xff09 分享给一直支持阿木的大家 百度网盘下载地址 xff1a 链接 xff1a https pan baidu com s 1n9Pydi
  • 阿木社区pixhawk二次开发无人机参数测量报告

    为了更好的给无人机建模 xff0c 更好的给无人机建立数学模型 xff0c 用于算法开发 xff0c 我们测量了数据如下 xff1a 1 无人机绕三轴转动惯量的测量 在此我们利用双线摆来测量三个转动惯量 xff0c 其示意图和原理如下 xf
  • 千寻高精度定位系统能在pixhawk系统上使用成功吗?

    如何在不使用基站的情况下 xff0c 得到精确的位置数据 xff1f 如何给在无人车的开发提供全国范围的厘米级精确定位数据 xff1f 如何在基于pixhawk上的无人车 xff0c 无人船 xff0c 无人机上解决以上问题 xff1f 为
  • 在ubuntu server上安装raspi-config并开启CSI摄像头

    我的树莓派安装了ubuntu server18 04 xff0c 由于不是树莓派官方系统raspian xff0c 因此不自带raspi config 启动摄像头需要用到官方的raspi config配置程序 xff0c 进入官网地址 xf
  • 【测试】QGC地面站开发课程完结篇--一站多机控制测试说明

    阿木实验室去年推出的QGC地面站开发实战课程 xff0c 随着地面站控制多架飞机的测试的成功 xff0c 课程全部完结 xff0c 以下是我们户外测试最终版地面站的测试视频 xff1a 视频地址 xff1a https v qq com x
  • sdf文件使用plugin

  • VGG16训练RAF-DB

    使用VGG16对本地数据集RAF DB中的basic图片进行训练 xff0c 官方已经在图片命名时分好了train与test xff0c train和test的label在同一个txt文件里 xff0c 方便起见 xff0c 把这两种lab
  • CMake编译opencv(测试)

    WORKIGN FOR THE WOLF 单编译OpenCV来测试项目 项目名称 span class token operator span 自定义 span class token function project span span
  • 从零开始学习SLAM:openCV

    继续跟随 视觉SLAM十四讲 学习SLAM问题 xff0c 由于理论方面已经有一些研究 xff0c 主要缺乏的是在LINUX下的实战开发能力 xff0c 因而从代码开始分析入手 xff0c 同时对C 43 43 11进行回顾 1 openC
  • 对博士学位说永别

    来自王垠 xff1a http blog sina com cn s blog 5d90e82f0101atzr html 经过深思熟虑之后 xff0c 我决定再次 抛弃 我的博士学位 这是我第三次决定离开博士学位 xff0c 也应该是最后
  • python web开发——Django基于类的视图

    简介 视图是一个可调用对象 xff0c 可以接收一个请求然后返回一个响应 这个可调用对象不仅仅限于函数 xff0c Django 同时提供一些可以用作视图的类 它们允许你结构化你的视图并且利用继承和混合重用代码 后面我们将介绍一些用于简单任
  • 使用docker安装ubuntu镜像

    使用docker安装ubuntu镜像 查找Ubuntu镜像 docker search ubuntu 安装Ubuntu镜像 docker pull ubuntu 查看docker镜像 docker images 运行docker镜像 doc
  • Ubuntu安装kalibr

    Ubuntu安装kalibr错误集锦 一 安装过程 ros参考 xff1a https blog csdn net Mua111 article details 107513509 kalibr安装参考 xff1a https blog c
  • 树莓派4b ubuntu系统开启串口

    树莓派4b安装ubuntu server18后如何开启串口 xff1f 树莓派4b的引脚图如下 xff1a 其中GPIO14和GPIO15是硬件串口 因为我安装的不是Raspian系统 xff0c 因此无法用raspi config打开该串
  • 惯性导航原理(1):导航坐标系及相互转换

    一 导航坐标系转换 坐标系介绍1 惯性坐标系 xff08 地心惯性坐标系 xff09 i系2 地球坐标系 xff08 地心地固坐标系 xff09 e系3 WGS 84坐标系 xff08 常用 xff09 blh坐标系4 当地水平地理坐标系g
  • win7系统下安装Ubuntu20.04.5系统保姆级教程

    一 制作u盘启动盘 准备工作 xff1a 一个空的8G大小的u盘 43 ultraISO软件 43 ubuntu系统的镜像文件 1 下载并安装ultraISO软件 下载地址 xff1a 百度网盘 请输入提取码 提取码 xff1a jv6a
  • 手把手带你免费打嘉立创pcb板

    手把手带你免费打嘉立创pcb板 前言一 熟悉规则二 下单1 下载安装下单助手2 领劵 注意 前言 嘉立创的新规则 xff1a 上个月消费没有满20的话只支持立创EDA画的板子 一 熟悉规则 嘉立创的免费规则和板子工艺要求如下 xff0c 大
  • ADRC学习与参数整定心得

    ADRC xff0c 中文名是自抗扰控制技术 继承了经典PID控制器的精华 xff0c 对被控对象的数学模型几乎没有任何要求 xff0c 又在其基础上引入了基于现代控制理论的状态观测器技术 xff0c 将抗干扰技术融入到了传统PID控制当中
  • ArUco相关

    ArUco相关 ArUco xff0c 一个开源的微型的现实增强库 https blog csdn net bashendixie5 article details 113769010 Aruco码估计相机位姿初步 xff01 xff01
  • ArUco

    文章目录 一 ArUco简介二 Marker和字典三 步骤1 创建Marker xff08 Marker Creation xff09 2 检测Marker xff08 Marker Detection xff09 3 姿态估计 xff08