【计算机视觉】 相机姿态估计之标记检测-ArUco钻石标记的检测4

时间:2021-09-07 20:27:00

ArUco钻石标记的检测

来源OpenCV 

.http://docs.opencv.org/master/d5/d07/tutorial_charuco_diamond_detection.html


效果图


【计算机视觉】 相机姿态估计之标记检测-ArUco钻石标记的检测4发现钻石标记


【计算机视觉】 相机姿态估计之标记检测-ArUco钻石标记的检测4发现钻石轴


说明



ChArUco钻石标记(或者只是钻石标记)是一个棋盘由3 x3广场和4 ArUco标记在白色方块。 类似于ChArUco标识板在外表,然而它们在概念上不同。

【计算机视觉】 相机姿态估计之标记检测-ArUco钻石标记的检测4钻石标记的例子

在两者中,ChArUco标识板和钻石标记,检测是基于前面发现ArUco标记。 ChArUco的情况下,使用标记选择通过直接看他们的标识符。 这意味着如果一个标记(包括在标识板)上发现的一个形象,它会自动认为属于标识板。 此外,如果找到标志板图像中不止一次,它将产生歧义,因为系统无法知道哪一个应该用于标识板

另一方面,钻石标记的检测不是基于标识符。 相反,他们检测是基于相对位置的标记。 因此,标记标识符可以重复相同的钻石或在不同的钻石,他们可以同时检测到没有歧义。 然而,由于发现标记的复杂性,基于他们的相对位置,钻石标记的大小是有限的3 x3广场和4标记。

如在一个ArUco标记,每个钻石标记由4角和标识符。 四个角对应4棋盘角标记和标识符实际上是一组4个数字,这是四个ArUco标记的标识符在钻石。

钻石标记是有用的在这些场景重复标记应该允许。 例如:

  • 增加的数量的单一标记标识符使用钻石标记的标志。 他们将允许到N ^ 4种不同的id,在N标记的数量使用字典。
  • 给的四个标记一个概念性的含义。 例如,的四个标记id可以用来指示标志的规模(即广场的大小),这样可以找到相同的钻石与不同大小只通过改变一个环境的四个标记和用户不需要手动显示每个人的规模。 这种情况下包含在 diamond_detector.cppsamples文件夹内文件的模块。

此外,作为它的角落棋盘的角落,他们可以用来准确的姿态估计。

钻石函数都包含在 <opencv2
/ aruco / charuco.hpp
>

ChArUco钻石创造

一颗钻石的形象可以很容易地创建使用标志 drawCharucoDiamond()函数。 例如:

cv::Mat diamondImage;cv::Ptr<cv::aruco::Dictionary> dictionary = cv::aruco::getPredefinedDictionary(cv::aruco::DICT_6X6_250);cv::aruco::drawCharucoDiamond(dictionary, cv::Vec4i(45,68,28,74), 200, 120, markerImage);

这将创建一个钻石标记图像,平方大小的200像素和120像素的标记大小。 标记的id在第二个参数给出 Vec4i对象。 的顺序标记id在钻石的布局是一样的标准ChArUco板,即前、左、右和底部。

产生的图像将会是:

【计算机视觉】 相机姿态估计之标记检测-ArUco钻石标记的检测4钻石标记

一个完整的工作包含在示例 create_diamond.cpp模块内的样本文件夹。

注意:样品现在通过命令行通过输入  OpenCV Commandline Parser. 。 这个文件的示例参数

"_path_/mydiamond.png" -sl=200 -ml=120 -d=10 -ids=45,68,28,74

ChArUco钻石检测

在大多数情况下,钻石标记的检测需要一个前检测ArUco标记。 检测标记后,钻石检测使用 detectCharucoDiamond()函数:

cv::Mat inputImage;float squareLength = 0.40;float markerLength = 0.25;...std::vector<int> markerIds;std::vector<std::vector< cv::Point2f>> markerCorners;// detect ArUco markerscv::aruco::detectMarkers(inputImage, dictionary, markerCorners, markerIds);std::vector<cv::Vec4i> diamondIds;std::vector<std::vector<cv::Point2f>> diamondCorners;// detect diamon diamondscv::aruco::detectCharucoDiamond(inputImage, markerCorners, markerIds, squareLength / markerLength, diamondCorners, diamondIds);

 detectCharucoDiamond()函数接收原始图像和前面的角落和ids检测标志。 必要的输入图像进行亚像素细分ChArUco角落。 它也接收率之间的广场大小和所需的标记尺寸,检测钻石的相对位置标记和插值ChArUco角落。

两个参数的函数返回检测到的钻石。 第一个参数, diamondCorners是一个数组,包含所有的四个角落发现了钻石。 它的格式类似于发现的角落 detectMarkers()函数,对于每一个钻石,角落中表示相同的顺序比ArUco标记,即顺时针方向从左上角。 第二个参数,返回 diamondIds,包含所有的id返回的钻石在角落 diamondCorners。 每个id是4的整数数组,可以代表 Vec4i

发现钻石可以使用的可视化函数 drawDetectedDiamonds()只接待形象和钻石的角落和ids:

...std::vector<cv::Vec4i> diamondIds;std::vector<std::vector<cv::Point2f>> diamondCorners;cv::aruco::detectCharucoDiamond(inputImage, markerCorners, markerIds, squareLength / markerLength, diamondCorners, diamondIds);cv::aruco::drawDetectedDiamonds(inputImage, diamondCorners, diamondIds);

结果都是一样的,所产生的 drawDetectedMarkers(),但印刷的四个ids钻石:

【计算机视觉】 相机姿态估计之标记检测-ArUco钻石标记的检测4发现钻石标记

一个完整的工作包含在示例 detect_diamonds.cpp模块内的样本文件夹。

注意:样品现在通过命令行通过输入OpenCV Commandline Parser OpenCV命令行解析器 。 这个文件的示例参数

-c="_path_/calib.txt" -dp="_path_/detector_params.yml" -sl=0.04 -ml=0.02 -d=10

ChArUco钻石构成的评估

自从ChArUco金刚石是由它的四个角落,它的姿势可以以同样的方式估计比单个ArUco标记,即使用 estimatePoseSingleMarkers()函数。 例如:

...std::vector<cv::Vec4i> diamondIds;std::vector<std::vector<cv::Point2f>> diamondCorners;// detect diamon diamondscv::aruco::detectCharucoDiamond(inputImage, markerCorners, markerIds, squareLength / markerLength, diamondCorners, diamondIds);// estimate posesstd::vector<cv::Vec3d> rvecs, tvecs;cv::aruco::estimatePoseSingleMarkers(diamondCorners, squareLength, camMatrix, distCoeffs, rvecs, tvecs);// draw axisfor(unsigned int i=0; i<rvecs.size(); i++)cv::aruco::drawAxis(inputImage, camMatrix, distCoeffs, rvecs[i], tvecs[i], axisLength);

函数将获得旋转和转换向量的每个钻石标记并将它们存储在 rvecs和 tvecs。 注意,钻石的角落是一个棋盘方角,因此,广场的长度必须为姿势估计,而不是标记的长度。 相机标定参数也是必需的。

最后,一个轴可以检查估计姿势是正确的使用 drawAxis():

【计算机视觉】 相机姿态估计之标记检测-ArUco钻石标记的检测4发现钻石轴

钻石构成的坐标系统将与Z轴的中心标记指出,在一个简单的姿势估计ArUco标志。


一个完整的工作包含在示例 detect_diamonds.cpp模块内的样本文件夹。

注意:样品现在通过命令行通过输入  OpenCV Commandline Parser.OpenCV命令行解析器 。 这个文件的示例参数

-c="_output path_/calib.txt" -dp="_path_/detector_params.yml" -sl=0.04 -ml=0.02 -d=10