open3d之常用marker调研

Marker类型

以下是找到的marker的种类,进行了统计如下,并对能找到源码或测试代码的marker进行了调试说明,若有遗漏,欢迎建议补充

名称图案论文仓库语言是否开源
ArUcoAutomatic generation and detection of highly reliable fiducial markers under occlusion地址c++,pytyhon
Diamond暂无仓库c++,pytyhon
ApriltagAprilTag: A robust and flexible visual fiducial system仓库c
STagSTag: A Stable Fiducial Marker System仓库c++
Pi-tagPi-Tag: A fast image-space marker design based on projective invariants仓库c++
ARToolkitARToolKit - Tinmith Augmented Reality代码地址c
reacTIVisionreacTIVision and TUIO: a tangible tabletop toolkit代码地址c++
ChilitagsChilitags - Quentin Bonnard仓库c++
ChromaTagChromaTag: A Colored Marker and Fast Detection Algorithm仓库c++
TopoTagTopoTag: A Robust and Scalable Topological Fiducial Marker System仓库c++
CCTagDetection and Accurate Localization of Circular Fiducials Under Highly Challenging Conditions仓库c++
RUNETagRUNE-Tag: A high accuracy fiducial marker with strong occlusion resilience仓库c++

ArUco Marker

1.简介

ArUco标记最初由S.Garrido-Jurado等人在2014年发表的论文Automatic generation and detection of highly reliable fiducial markers under occlusion中提出。ArUco的全称是Augmented Reality University of Cordoba,下面给出ArUco标记的一些示例。

ArUco标记是可用于摄像机姿态估计的二进制方形基准标记。它的主要优点是检测简单、快速,并且具有很强的鲁棒性。ArUco 标记是由宽黑边框和确定其标识符(id)的内部二进制矩阵组成的正方形标记。ArUco标记的黑色边框有助于其在图像中的快速检测,内部二进制编码用于识别标记和提供错误检测和纠正。ArUco标记尺寸的大小决定内部矩阵的大小,例如尺寸为 4x4 的标记由 16 位二进制数组成。   ArUco标记的尺寸可以任意的更改,为了成功检测可根据对象大小和场景选择合适的尺寸。在实际使用中,如果标记的尺寸太小,可能无法检测到它,这时可以选择更换较大尺寸的标记,或者将相机离标记更近一些。

  在机器人应用中,可以将这些标记沿着仓库机器人的路径放置。当安装在机器人上的摄像头检测到这些标记时,由于每个标记都有唯一的ID,并且标记在仓库中的放置位置已知,因此就可以知道机器人在仓库中的精确位置。

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

2. Marker和字典

一个ArUco marker是一个二进制方形标记,它由一个宽的黑边和一个内部的二进制矩阵组成,内部的矩阵决定了它们的id。黑色的边界有利于快速检测到图像,二进制编码可以验证id,并且允许错误检测和矫正技术的应用。marker的大小决定了内部矩阵的大小

3.通过使用OpenCV生成ArUco标记图

  使用OpenCV可轻松生成这些标记。OpenCV中的Aruco模块总共有25个预定义的标记词典。每个词典中所有的Aruco标记均包含相同数量的块或位(例如4×4、5×5、6×6或7×7),且每个词典中Aruco标记的数量固定(例如50、100、250或1000)。接下来将展示如何使用Python中生成和检测各种aruco标记。

  调用getPredefinedDictionary()函数加载包含250个标记的字典,其中每个标记都是6×6位二进制模式。具体代码在下面给出。

import cv2 as cv
import numpy as np
​
# 创建
dictionary = cv.aruco.getPredefinedDictionary(dict=cv.aruco.DICT_6X6_250)
img = cv.aruco.drawMarker(dictionary, id=33, sidePixels=200, borderBits=1)
# id         指定该Marker在字典中的索引ID,该例中合法的ID为[0, 249]
# sidePixels 指定输出的Marker图像的尺寸,单位是像素,该例中为(200,200)
#            如果使用DICT_6X6_250,则编码区域被划分为6X6个等大小的模块
#            参数borderBits=1,所以整个标志块区域被划分为8X8个等大小的模块
#            模块的尺寸必须大于一个像素。因此该例中,此参数最小值为8
# borderBits 指定编码区域到标志块区域的距离。单位是编码模块。取值必须大于等于1
print(img.shape)
cv.imshow("Aruco Marker", img)
cv.waitKey()
​

  代码中drawMarker函数可以从由250个aruco标记组成的集合中选择给定id(第二个参数– 33)的标记,这250个标记的id由0~249表示。drawMarker函数的sidePixels决定生成的标记的大小,在上面的示例中,它将生成200×200像素的图像。borderBits是边界宽度参数,它决定应将多少位(块)作为边界添加到生成的二进制图案中。

  在上面的代码中,将在6×6生成的图形周围添加1位的边界,以在200×200像素的图像中生成8×8位的图像。上述代码生成的aruco标记如下图所示。 在这里插入图片描述   在实际应用时,我们可能需要生成多个标记。之后我们只需要将这些标记打印出来就可以直接使用了。

3.检测Aruco标记

3.1 创建检测图像
# 创建图像
img_detected = np.ones((800, 600), dtype=np.uint8) * 255
img_detected[50:100, 50:100] = cv.aruco.drawMarker(dictionary, id=23, sidePixels=50, borderBits=1)
img_detected[350:400, 350:400] = cv.aruco.drawMarker(dictionary, id=18, sidePixels=50, borderBits=1)
img_detected[450:500, 450:500] = cv.aruco.drawMarker(dictionary, id=33, sidePixels=50, borderBits=1)
cv.imshow("img_detected", img_detected)
cv.waitKey()
​
3.2 检测
# 检测
corners, ids, rejectedImgPoints = cv.aruco.detectMarkers(image=img_detected,
                                                         dictionary=dictionary,
                                                         parameters=None)
img_color = cv.cvtColor(img_detected, cv.COLOR_GRAY2BGR)
cv.aruco.drawDetectedMarkers(img_color, corners, ids)
cv.imshow("DectectedMarker", img_color)
cv.waitKey()
 

4.一些API的介绍

  姿态估计问题就是要确定某个三维物体的方位指向问题,也就是确定以该物体为中心原点的一个坐标系。

getPredefinedDictionary()
dictionary = cv.aruco.getPredefinedDictionary(dict=cv.aruco.DICT_6X6_250)
  • 关于DICT_4X4_50含义 DICT是dictionary的缩写,6×6表示去掉一个宽的黑边后的网格大小,如下图所示是6×6的,蓝色的矩形框所示。 50表示每个字典中的Marker数目,有效的id数字范围是0到49。不在有效区间的特定id将会产生异常。 在这里插入图片描述 上图为一个典型的ArUco marker,去除黑色边框后为6X6的格子(黑色表示0,白色表示1),6X6的格子的外边缘为黑色。

id的计算方法:
1 0 0 1 1 0
1 0 0 0 1 1
0 0 0 0 0 1
0 0 0 1 1 1
1 1 0 0 1 1
0 1 1 1 1 0
​
每行组成一个二进制数,将这6个二进制数进行相加转换为十进制,就是id。
​
enum PREDEFINED_DICTIONARY_NAME {
    DICT_4X4_50 = 0,
    DICT_4X4_100,
    DICT_4X4_250,
    DICT_4X4_1000,
    DICT_5X5_50,
    DICT_5X5_100,
    DICT_5X5_250,
    DICT_5X5_1000,
    DICT_6X6_50,
    DICT_6X6_100,
    DICT_6X6_250,
    DICT_6X6_1000,
    DICT_7X7_50,
    DICT_7X7_100,
    DICT_7X7_250,
    DICT_7X7_1000,
    DICT_ARUCO_ORIGINAL,
    DICT_APRILTAG_16h5,     ///< 4x4 bits, minimum hamming distance between any two codes = 5, 30 codes
    DICT_APRILTAG_25h9,     ///< 5x5 bits, minimum hamming distance between any two codes = 9, 35 codes
    DICT_APRILTAG_36h10,    ///< 6x6 bits, minimum hamming distance between any two codes = 10, 2320 codes
    DICT_APRILTAG_36h11     ///< 6x6 bits, minimum hamming distance between any two codes = 11, 587 codes
};

注: marker corner的顺序是起点为左上角, 顺时针 注: DICT_ARUCO_ORIGINAL: 为DICT_5X5_1024

drawMarker()
  • 函数作用:detectMarkers函数用于检测和确定标记角点的位置。

dictionary = cv.aruco.getPredefinedDictionary(dict=cv.aruco.DICT_6X6_250)
img = cv.aruco.drawMarker(dictionary, id=33, sidePixels=200, borderBits=1)

  首先,我们通过选择aruco模块中一个预定义的字典来创建一个字典对象,具体而言,这个字典是由250个marker组成的,每个marker的大小为6x6bits(DICT_6X6_250)

drawMarker的参数如下:

  • 第一个参数是之前创建的字典对象(带有标记的场景图像)。

  • 第二个参数是marker的id(用于生成标记的字典),成功检测到的标记将存储在markerCorners中,在这个例子中选择的是字典DICT_6X6_250第23个marker。注意到每个字典是由不同数目的Marker组成的,在这个例子中,有效的Id数字范围是0到249。不在有效区间的特定id将会产生异常。

  • 第三个参数,200,是输出Marker图像的大小。在这个例子中,输出的图像将是200x200像素大小。注意到这一参数需要满足能够存储特定字典 的所有位。所以,举例而言,你不能为6x6大小的marker生成一个5x5图像(这还没有考虑到Marker的边界)。除此之外,为了避免变形,这一参数最好和位数+边界的大小成正比,至少要比marker的大小大得多(如这个例子中的200),这样变形就不显著了。。

  • 最后一个参数是一个可选的参数,它指定了Marker黑色边界的大小。这一大小与位数数目成正比。例如,值为2意味着边界的宽度将会是2的倍数。默认的值为1。 生成的图像如下: 在这里插入图片描述

estimatePoseSingleMarkers()
cv.aruco.estimatePoseSingleMarkers(v_marker_corner, marker_size, cameraMatrix, distCoeffs, rvecs, tvecs)
  • 函数作用:估计marker在相机坐标系中的3D位姿。 参数:

  • 第一个参数:已检测marker角点的的向量

  • 第二个参数:marker的尺寸

  • 第三个参数:相机的内参矩阵

  • 第四个参数:相机的畸变系数

  • 第五个参数:输出marker坐标系到相机坐标系的旋转变换矩阵R

  • 第六个参数:输出marker坐标系到相机坐标系的旋转变换矩阵T 注: marker坐标系用marker的位置有关, z轴向外。

6.对aruco标记进行姿态估计的可视化显示

camera_matrix = np.array([[532.79536562, 0, 342.4582516],
                          [0, 532.91928338, 233.90060514],
                          [0, 0, 1.]])
dist_coefs = np.array([-2.81086258e-01, 2.72581018e-02, 1.21665908e-03, -1.34204275e-04, 1.58514022e-01])
​
rvecs, tvecs, _objPoints = cv.aruco.estimatePoseSingleMarkers(corners, 0.05, camera_matrix, dist_coefs)
for i in range(len(rvecs)):
    cv.aruco.drawAxis(img_color, camera_matrix, dist_coefs, rvecs[i], tvecs[i], 0.05)
​
cv.imshow("Pose Estimation", img_color)
cv.waitKey()
​

效果:

Diamond Markers

1.简介

Chessboard具有高的交点精度,但是交点提取比较困难。ArUco能够快速检测,但即使使用亚像素精度提取,提取的交点精度也不甚理想。ChArUco集成了Chessboard的高精度与ArUco易用性的优点。

ChArUco菱形标记(或简称菱形标记)是一个由3x3个方格和4个在白色方格内的ArUco标记组成的棋盘。它在外观上与ChArUco板相似,但在概念上有所不同。

ChArUco board和Diamond marker的检测都基于先前检测到的ArUco标记。Charuco使用的标记是通过直接查找其标识符选择的。这意味着,如果在图像上找到一个标记(包含在板中),它将自动假定属于板。此外,如果一个标记在图像中被发现不止一次,它将产生歧义,因为系统无法知道哪一个应该用于该板;Diamond marker的检测不是基于标识符。相反,它们的检测是基于标记的相对位置。因此,标记标识符可以在同一个菱形中或在不同的菱形之间重复,并且可以同时检测到,而不会产生歧义。然而,由于基于其相对位置查找标记的复杂性,钻石标记的大小限制为3x3正方形和4个标记。

与单个ArUco标记一样,每个Diamond marker由4个角和一个标识符组成。四个角对应于标记中的四个棋盘角,标识符实际上是一个由4个数字组成的数组,这些数字是菱形内部四个ArUco标记的标识符。

2. 创建ChArUco Diamond

# 创建
marker_ids = np.array([45, 68, 28, 74])
squareLength = 200
markerLength = 120
dictionary = cv2.aruco.getPredefinedDictionary(dict=cv2.aruco.DICT_6X6_250)
img = cv2.aruco.drawCharucoDiamond(dictionary, ids=marker_ids, squareLength=squareLength, markerLength=markerLength)
print(img.shape)
cv2.imshow("ChArUco Diamond", img)
cv2.waitKey()

参数示意图

3.ChArUco Diamond检测

corners, ids, rejectedImgPoints = cv2.aruco.detectMarkers(image=img,
                                                          dictionary=dictionary)

diamond_corners, diamond_ids = cv2.aruco.detectCharucoDiamond(img,
                                                              markerCorners=corners,
                                                              markerIds=marker_ids,
                                                              squareMarkerLengthRate=squareLength / markerLength)
img = cv2.cvtColor(img, cv2.COLOR_GRAY2BGR)
img = cv2.aruco.drawDetectedDiamonds(img, diamond_corners, diamond_ids)
print(img.shape)
cv2.imshow("ChArUco Diamond", img)
cv2.waitKey()

4. 位姿估计

camera_matrix = np.array([[532.79536562, 0, 342.4582516],
                          [0, 532.91928338, 233.90060514],
                          [0, 0, 1.]])
dist_coefs = np.array([-2.81086258e-01, 2.72581018e-02, 1.21665908e-03, -1.34204275e-04, 1.58514022e-01])
rvecs, tvecs, _objPoints = cv2.aruco.estimatePoseSingleMarkers(diamond_corners, markerLength, cameraMatrix=camera_matrix, distCoeffs=dist_coefs)

for i in range(len(rvecs)):
    cv2.drawFrameAxes(img_color, camera_matrix, dist_coefs, rvecs[i], tvecs[i], length=50, thickness=2)

cv2.imshow("Pose Estimation", img_color)
cv2.waitKey()

Apriltag

1.简介

AprilTag 是一个视觉基准系统,可用于多种任务,包括增强现实,机器人和相机校准。通过特定的标志(与二维码相似,但是降低了复杂度以满足实时性要求),可以快速地检测标志,并计算相对位置。它可以从普通打印机创建目标,AprilTag检测软件可以计算标签相对于相机的精确3D位置,方向和ID。AprilTag库在C中实现,没有任何外部依赖关系。它被设计为易于包含在其他应用程序中,并且可移植到嵌入式设备中。即使在手机级处理器上也可以实现实时性能。

2. Apriltag图像生成

2.1 通过OpenMV生成

下载openmv软件

  安装后打开,依次按照图示进行,选择相应文件夹生成即可

img

▲ 图2.1.2  对应的不同家族的Apriltag码

2.2 官网下载

 实际上,在网络上所有的Apriltag的图片已经被生成存储,可以直接下使用:

  • mirrors / AprilRobotics / apriltag-imgs

  请注意,所有序列的Apriiltag图片个数非常多,所以下载使用在解压缩的时候花费很多的时间和磁盘存储空间。

2.3 网页图片

 如果只是使用少量的Apriltag做实验,可以直接在一些网页上提取,鼠标右键存储。

2.4 程序生成
sudo apt install python-pyx
rosrun tagslam make_tag.py --nx 1 --ny 1 --marginx 0.00 --marginy 0.00 --tsize 0.16 --tspace 0.0 --startid 4 --tfam t36h11 --borderbits 1

3. 检测

检测代码仓库: https://github.com/swatbotics/apriltag 可以通过以下指令安装其python接口,但需要注意,提供pypi库的并非该仓库的作者

pip3 install apriltag
import apriltag
import cv2
    
img = cv2.imread('/home/rvbust/Pictures/1111.png', cv2.IMREAD_GRAYSCALE)

detector = apriltag.Detector() result = detector.detect(img) print(result)

输出结果为:

[Detection(tag_family=b'tag36h11', tag_id=20, hamming=0, goodness=0.0, decision_margin=126.08333587646484, homography=array([[ 1.73373238e-16,  7.06417257e-01, -1.36868344e+00],
[-7.06417257e-01,  3.16654215e-16, -1.10377696e+00],
[-5.31125879e-29,  1.65748568e-17, -4.41510786e-02]]), center=array([31., 25.]), corners=array([[47.,  9.],
[47., 41.],
[15., 41.],
[15.,  9.]]))]

使用下面的脚本可进行位姿估计 python apriltag.py -c -k '(765.00, 764.18, 393.72, 304.66)' -s .127 ../images/mapping_feb_2014/*JPG

TopoTag

1.简介

	TopoTag是一种鲁棒且可扩展的拓扑基准标记系统,它支持从单个图像进行可靠和准确的姿态估计。TopoTag在标记检测中使用拓扑和几何信息,以实现更高的鲁棒性。拓扑信息被广泛用于2D标记检测,并且进一步用于ID解码的相应几何信息。通过利用所有TopoTag顶点实现稳健的3D姿态估计。TopoTag不必像以前的系统那样牺牲比特来获得更高的召回率和精度,它可以使用完整的比特来进行ID编码。TopoTag支持数万个唯一ID,并可轻松扩展到数百万个唯一标签,从而实现巨大的可扩展性。

2.论文地址

3.检测源码

暂未找到开源的代码,官方提供了测试的exe及数据

ChromaTag

1.简介

ChromaTag是一种彩色基准标记和快速检测算法。它最初发表于ICCV 2017(见下文引文)。该方法通过使用颜色信息来快速剔除错误检测,并最终在灰度图下提升定位精度。

2.marker的下载地址

3.代码仓库

源代码仓库:https://github.com/CogChameleon/ChromaTag 原仓库代码存在一些bug及不兼容opencv4.X,我已经修复,仓库地址:https://github.com/ancy397031272/ChromaTag

4.检测效果

RUNETag

1.简介

2.代码仓库

CCTag

1.简介

检测由同心圆组成的CCTag标记

2.代码仓库

该仓库代码实现论文. Detection and Accurate Localization of Circular Fiducials Under Highly Challenging Conditions,支持CPU和GPU

3.maker下载地址

4.源码编译

# 下载源码 
git clone git@github.com:alicevision/CCTag.git
# 下载最新的TBB 
https://github.com/oneapi-src/oneTBB/releases/tag/v2021.7.0
# 修改CmakeList.txt, 设置TBB路径
set(TBB_DIR /home/rvbust/Downloads/oneapi-tbb-2021.7.0/lib/cmake/tbb/)  # 路径设置
find_package(TBB 2021.5.0 CONFIG REQUIRED)
# 编译
mkdir build && cd build
make -j7
    

5.检测结果

./build/Linux-x86_64/detection -n 3 -i sample/01.png

STag

1.简介

这是一种稳定的基准标记系统,从作者的展示来看,其稳定性高于ARToolKit+, ArUcon, RUNE-Tag

2.代码下载地址

3.marker下载地址

Pi-Tag

1. 简介

2.论文地址

3.代码下载地址

4.marker生成代码

5.检测效果

ARToolkit

1.简介

2.代码地址

reacTIVision

1.简介

2.代码地址

Chilitags

1.简介

chilttags演示视频地址

2.制作marker

1)可以从以下地址中下载

https://github.com/chili-epfl/chilitags/releases/download/2.0.0/tags.zip

2)使用仓库中的脚本生成

/tools/creator

3.代码地址

4.检测效果

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值