视觉标记定位aruco使用

2023-05-16

本文的目的是实现生成一张marker broad图片,告诉标记检测程序tag在真实世界中的实际大小。
检测成功后得到marker的id,四个角点坐标,marker到相机的平移和旋转。

1.下载安装参考

opencv 中的aruco源码下载要到下面地址
opencv 中的aruco源码下载
https://github.com/opencv/opencv_contrib/tree/master/modules/aruco
https://github.com/opencv/opencv_contrib/releases/tag/3.3.0

2.生成单个marker图片

程序如下

#include <opencv2/opencv.hpp>
#include <opencv2/aruco.hpp>
#include <opencv2/calib3d/calib3d.hpp>
#include "opencv2/core/core.hpp"
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <iostream>

using namespace std;
using namespace cv;

int main()
{
    cv::Mat markerImage;
    cv::Ptr<cv::aruco::Dictionary> dictionary = 	cv::aruco::getPredefinedDictionary(cv::aruco::DICT_6X6_250);
    cv::aruco::drawMarker(dictionary, 23, 200, markerImage, 1);
    imwrite("./aruco_tag.png",markerImage);
    imshow("test", markerImage);//显示marker
    waitKey();
    return 0;
}

cv::aruco::drawMarker
第一个参数是之前创建的Dictionary对象。
第二个参数是marker的id,在这个例子中选择的是字典DICT_6X6_250 的第23个marker。注意到每个字典是由不同数目的Marker组成的,在这个例子中的字典中,有效的Id数字范围是0到249。不在有效区间的特定id将会产生异常。
三个参数,200,是输出Marker图像的大小。在这个例子中,输出的图像将是200x200像素大小。注意到这一参数需要满足能够存储特定字典 的所有位。举例来说,你不能为6x6大小的marker生成一个5x5图像(这还没有考虑到Marker的边界)。除此之外,为了避免变形,这一参数最好和位数+边界的大小成正比,或者至少要比marker的大小大得多(如这个例子中的200),这样变形就不显著了
第四个参数是输出的图像。
最终,最后一个参数是一个可选的参数,它指定了Marer黑色边界的大小。这一大小与位数数目成正比。例如,值为2意味着边界的宽度将会是2的倍数。默认的值为1。

3.打印并标定相机内参

注意,打印的时候如果用像素为200200的图像打印,实际打印大小为20cm20cm,那么一个像素对应1毫米。
内参标定就不介绍了,此实验使用内参为

intrinsic_matrix: !!opencv-matrix
   rows: 3
   cols: 3
   dt: d
   data: [ 420.019, 0., 330.8676, 0.,
       419.6044, 217.8731, 0., 0., 1. ]
distortion_vector: !!opencv-matrix
   rows: 1
   cols: 4
   dt: d
   data: [ -0.3549, 0.1151, -0.0035, -0.0029 ]

的相机拍出来的图像如下
在这里插入图片描述

4.检测marker并得到id和相对位移

确定好实际打印出来的marker的边长和内参就可以检测并计算了。
其中markerlength表示marker的实际物理长度。
使用上面的图像和内参程序如下

#include <opencv2/opencv.hpp>
#include <opencv2/aruco.hpp>
#include <opencv2/calib3d/calib3d.hpp>
#include "opencv2/core/core.hpp"
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <iostream>
#include <eigen3/Eigen/Core>
#include <eigen3/Eigen/Geometry>
#include <opencv2/core/eigen.hpp>

using namespace std;
using namespace cv;

int main()
{
    cv::Mat m_image=imread("./mark.jpg");
    if(m_image.empty())
    {
        cout<<"m_image  is empty"<<endl;
        return 0;
    }
    //read para
   double markerlength=0.105;
   cv::Mat intrinsics = (Mat_<double>(3, 3) <<
                         420.019, 0.0, 330.8676,
                         0.0,419.6044, 217.8731,
                         0.0, 0.0, 1.0);

    cv::Mat distCoeffs=(cv::Mat_<double>(4, 1) <<  -0.3549, 0.1151, -0.0035, -0.0029);
    cv::Mat  imageCopy;
    m_image.copyTo(imageCopy);
    cv::Ptr<cv::aruco::Dictionary> dictionary = cv::aruco::getPredefinedDictionary(cv::aruco::DICT_6X6_250);

    std::vector<int> ids;
    std::vector<std::vector<cv::Point2f>> corners;
    cv::aruco::detectMarkers(m_image, dictionary, corners, ids);//检测靶标
    // if at least one marker detected
    if (ids.size() > 0) {
        cv::aruco::drawDetectedMarkers(imageCopy, corners, ids);//绘制检测到的靶标的框
        for(unsigned int i=0; i<ids.size(); i++)
        {
           std::vector<cv::Vec3d> rvecs, tvecs;
          cv::aruco::estimatePoseSingleMarkers(corners[i], markerlength, intrinsics, distCoeffs, rvecs, tvecs);//求解旋转矩阵rvecs和平移矩阵tvecs
            cv::aruco::drawAxis(imageCopy,intrinsics,distCoeffs, rvecs[i], tvecs[i], 0.1);
            //3.rotaion vector to eulerAngles
            cv::Mat rmat;
            Rodrigues(rvecs[i], rmat);
            Eigen::Matrix3d rotation_matrix3d;
            cv2eigen(rmat,rotation_matrix3d);
            Eigen::Vector3d eulerAngle = rotation_matrix3d.eulerAngles(0,1,2);//(0,1,2)表示分别绕XYZ轴顺序,即 顺序,逆时针为正
            cout<<"pitch "<<eulerAngle.x()<<"yaw "<<eulerAngle.y()<<"roll"<<eulerAngle.z()<<endl;
            cout<<"x= "<<tvecs[i][0]<<"y="<<tvecs[i][1]<<"z="<<tvecs[i][2]<<endl;
        }
    }
    cv::imshow("out", imageCopy);
    cv::waitKey();

    return 0;
}

其中
The parameters of detectMarkers are:
The first parameter is the image where the markers are going to be detected.
The second parameter is the dictionary object, in this case one of the predefined dictionaries (DICT_6X6_250).
The detected markers are stored in the markerCorners and markerIds structures:
markerCorners is the list of corners of the detected markers. For each marker, its four corners are returned in their original order (which is clockwise starting with top left). So, the first corner is the top left corner, followed by the top right, bottom right and bottom left.
markerIds is the list of ids of each of the detected markers in markerCorners. Note that the returned markerCorners and markerIds vectors have the same sizes.
The fourth parameter is the object of type DetectionParameters. This object includes all the parameters that can be customized during the detection process. This parameters are commented in detail in the next section.
The final parameter, rejectedCandidates, is a returned list of marker candidates, i.e. those squares that have been found but they do not present a valid codification. Each candidate is also defined by its four corners, and its format is the same than the markerCorners parameter. This parameter can be omitted and is only useful for debugging purposes and for ‘refind’ strategies (see refineDetectedMarkers() ).

5实验效果

输出

pitch 3.12894yaw -0.0187251roll-1.5281
x= -0.011554y=-0.0038433z=0.17224

在这里插入图片描述

6.生成多个marker组成的board

参考http://www.pianshen.com/article/2639341324/

#include <opencv2/opencv.hpp>
#include <opencv2/aruco.hpp>
#include <opencv2/calib3d/calib3d.hpp>
#include "opencv2/core/core.hpp"
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <iostream>

using namespace std;
using namespace cv;

int main()
{
    int markersX = 5;//X轴上标记的数量
    int markersY = 5;//Y轴上标记的数量   本例生成5x5的棋盘
    int markerLength = 100;//标记的长度,单位是像素
    int markerSeparation = 20;//每个标记之间的间隔,单位像素
    int dictionaryId = cv::aruco::DICT_4X4_50;//生成标记的字典ID
    int margins = markerSeparation;//标记与边界之间的间隔

    int borderBits = 1;//标记的边界所占的bit位数
    bool showImage = true;

    Size imageSize;
    imageSize.width = markersX * (markerLength + markerSeparation) - markerSeparation + 2 * margins;
    imageSize.height =
        markersY * (markerLength + markerSeparation) - markerSeparation + 2 * margins;

    Ptr<aruco::Dictionary> dictionary =
        aruco::getPredefinedDictionary(aruco::PREDEFINED_DICTIONARY_NAME(dictionaryId));

    Ptr<aruco::GridBoard> board = aruco::GridBoard::create(markersX, markersY, float(markerLength),
        float(markerSeparation), dictionary);

    // show created board
    Mat boardImage;
    board->draw(imageSize, boardImage, margins, borderBits);

    if (showImage) {
        imwrite("./aruco_tag_board.png",boardImage);
        imshow("board", boardImage);
        waitKey(0);
    }

    return 0;
}

参考文献
https://blog.csdn.net/A_L_A_N/article/details/83657878

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

视觉标记定位aruco使用 的相关文章

  • 【OpenCV3.2】Detection of ArUco Markers 翻译OpenCV文档:ArUco Marker的检测

    这个其实是翻译的opencv的官方文档的aruco部分 https docs opencv org 3 1 0 d5 dae tutorial aruco detection html 视觉降落的二维码检测用到这里面 摘自 xff1a ht
  • SLAM学习——使用ARUCO_marker进行AR投影

    转载自 xff1a https blog csdn net Kalenee article details 90148599 SLAM学习 使用ARUCO marker进行AR投影 white Learner 2020 06 06 15 2
  • 我们可以看看美团的无人机二维码降落,也是用的aruco二维码

    摘自 xff1a https mp weixin qq com s ZwjS74fWpSfHx5qk8biogw 其实最外面这个最大的方框就是个二维码 xff01 xff01 xff01 xff01 xff01 然后里面的白色区域有更小的二
  • aruco识别,python实现

    需要配置anaconda xff0c 用spyder进行python语言编辑 xff0c 实现对aruco码的编写 代码比较垃圾 xff0c 不喜勿喷 配置过程如下 xff1a 视觉系统的运行需要搭建视觉环境 xff0c 包括 xff0c
  • [OpenCV] aruco Markers识别

    reference http docs opencv org 3 1 0 d5 dae tutorial aruco detection html 姿态估计 xff08 Pose estimation xff09 在计算机视觉领域扮演着十分
  • 基于ArUco的视觉定位(三)

    一 ArUco之Marker Mapper 1 Marker Mapper简介 Mapping and Localization from Planar Markers是A V A小组基于ArUco开发的一个利用二维码建图与定位的项目 论文
  • 使用电脑摄像头计算aruco marker位姿(Python)

    一 效果图 刚做了一些尝试 xff0c 算两个aruco之间的距离 先算x方向 xff0c 用ID 61 12减去ID 61 13 xff0c tvec的三个坐标依次是Z Y X 所以 xff0c ID 61 12和ID 61 13的x距离
  • 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
  • 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
  • opencv中ArUco识别

    姿态估计 xff08 Pose estimation xff09 在 计算机视觉领域扮演着十分重要的角色 xff1a 机器人导航 增强现实以及其它 这一过程的基础是找到现实世界和图像投影之间的对应点 这通常是很困难的一步 xff0c 因此我
  • aruco板_基于arucoTag的简单slam

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

    ArUco 一个微型现实增强库的介绍及视觉应用 xff08 二 xff09 ArUco 一个微型现实增强库的介绍及视觉应用 xff08 二 xff09 一 第一个ArUco的视觉应用 首先介绍第一个视觉应用的Demo xff0c 这个应用场
  • ArUco----一个微型现实增强库的介绍及视觉应用(一)

    ArUco 一个微型现实增强库的介绍及视觉应用 xff08 一 xff09 ArUco 一个微型现实增强库的介绍及视觉应用 xff08 一 xff09 一 ArUco简介 ArUco是一个开源的微型的现实增强库 xff0c 目前好像已经集成
  • aruco二维码

    1 二维码的生成 简单方式 xff1a 直接在下面的网站上选择 xff0c 操作简单https chev me arucogen 网站界面如下 xff1a
  • Ros下Aruco模块的使用

    生成ARUCO ROS MARKER 链接 http chev me arucogen 首先启动ros roscore 打开相机节点 xff0c 在此提供usb相机与Realsense D435i的启动方法 xff1a roslaunch
  • 使用Realsense测试aruco_ros包

    01 准备工作 安装realsense ros安装aruco ros span class token builtin class name cd span ur ws src span class token function git s
  • Opencv Aruco识别(python)

    效果图 先上效果 代码 直接上代码 xff1a span class token operator span span class token operator span usr span class token operator span
  • 如何获得相机旋转? (阿鲁科图书馆)

    我一直在尝试了解下载 Aruco 库时包含的 aruco test cpp 程序的输出 输出具有以下格式 22 236 87 86 4296 422 581 78 3856 418 21 228 032 261 347 228 529 Tx

随机推荐

  • Simulink中从Workspace中读取时序数据的方法

    1 首先 xff0c 我从adams得到是时长5秒的500组加速度数据 xff0c 将其存为txt格式 并放入matlab路径中 xff0c 其第一列为时间序号 xff0c 234列为三轴的加速度数据 2 在workspace中使用 tex
  • 简单聊聊Betaflight的三种飞行模式

    大概查了一下网上介绍Betaflight飞行模式的文章很多 xff0c 讲了很多很全面 xff0c 但这里我们去粗取精 xff0c 只谈常用的三种模式Angle xff0c Horizon和Acro模式 下面的内容全部翻译自这个英文网站 1
  • Vim中快速定位到某一行的方法

    1 定位到第一行 xff1a 1 43 shift 43 G 2 定位到最后一行 xff1a shift 43 G 3 定位到第x行 xff1a x 43 shift 43 G 或在Vim中 xff1a xff1a x 补充 xff1a 在
  • PX4源码学习(一):结构概述

    最近在做PX4固件的移植开发工作 xff0c 由于之前没有这方面开发经验 xff0c 加之PX4源码又比较庞杂 xff0c 所以想要通过一点一点的学习梳理和实践 xff0c 使这部分工作能够尽快开展起来 博客中如有错误 xff0c 恳请大家
  • PX4(Pixhawk)和Audupilot(APM)的区别与联系

    一 各自的简要介绍 pixhawk是硬件平台 xff0c PX4是pixhawk的原生固件 xff0c 专门为pixhawk开发 APM xff08 Ardupilot Mega xff09 也是硬件 xff0c Ardupilot是APM
  • Makefile和Cmake的区别和联系

    最近在搞无人机飞控的学习 xff0c 大致了解了下PX4的文件结构和编译 xff0c 它的文件中有许多Makefile和Cmake文件 xff0c 对其在整个文件编译过程中的作用不甚了解 在进行一番查询后 xff0c 终于有了个大致的认识
  • 浮点数在计算机中的表示,程序中浮点数的取值和比较。

    小数的十进制 二进制转换 十进制 gt 二进制 整数部分除2取余 xff0c 小数部分乘2取整 考虑 8 25 整数部分8进行除2取余 xff0c 除2商4余0 除2商2余0 除2商1余0 除2商0余1 所以结果是1000 最后一个余数在最
  • 关于PX4系统移植的新的硬件平台一些尝试总结

    最近尝试将PX4的firmware v1 11 0移植到某stm32h7的飞控平台上 xff08 该飞控硬件 xff0c 适配ardupilot和betaflight的固件 xff0c 但不支持PX4 xff0c 跟厂家沟通过 xff0c
  • RTK中浮点解、固定解的区别

    1 RTK固定解 xff08 fix xff09 简言之 xff0c 拥有固定解意味着解算出了正确的解 在常规条件下 xff0c 你拥有了1 3cm的测量精度 2 RTK浮点解 xff08 float xff09 又称差分解 xff0c 此
  • 飞机的姿态角总结

    飞机的俯仰 横滚 航行角统称姿态角 是飞机机体系相对地理系的相对转角 1 航向角为机体纵轴OYb轴在水平面上投影与OYt之间的夹角 xff0c 取值范围为 0 xff0c 360 xff0c 以机体从北向东偏转为正 2 俯仰角为机体纵轴OY
  • Matlab一些设置记录

    在使用matlab时经常要查一些命令 xff0c 索性在这里整理做一个集合 1 设置figrue背景为白色 xff08 默认为灰色 xff0c 直接截图贴图使用时有一丢丢影响效果 xff09 set 0 39 defaultfigureco
  • 如何学好嵌入式的嵌入式

    近来嵌入式挺火 xff0c 于是大家都往这里挤 我想提醒大家的是 xff0c 嵌入式马上也会成为如今的软件业 在你进来之前请先考虑清楚 但只要我们真的学精了一样东西 xff0c 不管它将来变成什么样 xff0c 哪怕最后只剩下一个人 xff
  • Python全局变量和局部变量(超详细,纯干货,保姆级教学)

    全局变量定义 在函数外部定义的变量 所有函数内部都可以使用这个变量 局部变量定义 在函数内部定义的变量 这个变量只能在定义这个变量的函数内部使用 第一种 xff1a global定义全局变量在自定义函数内部 定义看起来一愣一愣的 xff0c
  • stm32——手动移植HAL库以及错误解决方案(以STM32F103ZE为例)

    寄存器编程的缺点 xff1a 代码可读性差 xff0c 二次开发难度大 xff0c 而且要每次都查阅用户手册 xff0c 非常麻烦 HAL库 xff1a HAL库封装出了一层通用性的接口 xff0c 标准化了一套通用性的接口 xff0c 大
  • MATLAB在线编辑器online

    话不多说直接上网址 https matlab mathworks com 这个和下载的MATLAB功能一模一样 xff0c 这是我找了几个例子运行出来的结果 xff0c 和我想要的一模一样 xff0c 不过对于大多数人而言 xff0c 这个
  • stm32——使用结构体描述寄存器映射

    将地址信息放在一个头文件中方便管理 xff0c 存放地址和偏移量 STM32的外设寄存器的组织形式是 基于基地址 43 寄存器偏移地址 比如 xff0c 在RCC的基地址基础上 xff0c 偏移0x00得到RCC CR寄存器 xff0c 偏
  • 江科大stm32-概述

    第一章 STM32概述 1 1 资源介绍 STM32F103C8T6 51单片机使用的是5V供电 xff0c 还有USB输出的电压也是5V xff0c 5V是不在这个供电电压范围内的 xff0c 不能直接给STM32供电 xff0c 如果是
  • 在eclipse中查看你用的tomcat的路径

    打开eclipse xff0c 选择window gt Preferences gt Server gt Runtime Environments选择你的tomcat然后点Edit xff0c 就会出现它的路径了
  • 安装龙蜥或CentOS 7时出现dracut- initqueue timeout解决方法

    在安装龙蜥7 9操作系统时 xff0c 出现dracut initqueue timeout starting starting timeout scripts报错 CentOS 7 9出现此问题也可以参考同样的方法 如何制作启动盘和系统盘
  • 视觉标记定位aruco使用

    本文的目的是实现生成一张marker broad图片 xff0c 告诉标记检测程序tag在真实世界中的实际大小 检测成功后得到marker的id 四个角点坐标 marker到相机的平移和旋转 xff11 xff0e 下载安装参考 openc