1. Aruco
Aruco是一个开源的相机姿态估计库,已经嵌入到Opencv的Contribute包中。
简单来说,这是类似于二维码的Marker,长这样:
结构:
- 黑色的邊界有利於快速檢測到圖像,同时,黑色边界的旁边需要有白色的space(用于检测)
- 二進制編碼可以驗證id,並且允許錯誤檢測和矯正技術的應用。
- marker的大小決定了內部矩陣的大小。例如,一個4x4的marker由16bits組成
功能:
- 检测这些Marker
- 标定相机参数
- 相机位姿估计(Oroku用于计算相机相对于某个Marker的位姿,Haruko用于多相机的定位)
1.1. 字典
markers的字典是在一個特殊應用中使用到的marker的集合
- 字典的大小就是组成字典所用到的Marker的数量
- marker的大小就是这些Marker的尺寸(bits)
2. Marker的创建
3. Marker的检测
输入一张有Marker的图像,检测所有Marker,并返回Marker信息:
- Marker的四个角点
- Marker的ID
检测过程主要分为两步
- 预检测Marker
- 根据内部编码筛选是否Marker
下面是需要检测Marker的图片
3.1. 检测的函数cv::aruco::detectMarkers
及参数
1 | cv::Mat inputImage; |
第一个参数是将要检测Marker的图像
第二个参数是字典对象,在这种情况下是一个预定义的字典( DICT_6X6_250 )
检测到的Marker存储在markerCorners和markerIds结构中
- markerCorners是检测到的Marker的角点列表。 对于每个Marker,其四个角以其原始顺序返回(从左上角开始顺时针)。 因此,第一个角是左上角,然后是右上角,右下角和左下角
- markerIds是markerIds中每个检测到的Marker的id列表。 请注意,返回的markerCorners和markerIds向量具有相同的大小
第四个参数是DetectionParameters类型的对象。 此对象包括可在检测过程中自定义的所有参数
最终参数rejectedCandidates是一个返回的Marker候选列表,即已找到的那些方格,但它们不提供有效的编码。 每个候选者也由其四个角定义,其格式与markerCorners参数相同。 此参数可以省略
3.2. 代码
1 |
|
检测结果
4. 位姿估计
在检测到这些Marker之后,下一件你可能要做的事情就是从它们那里获得相机的姿势。
为了进行摄像机的姿态估计,你需要知道你的摄像机的校准参数。 这些是相机矩阵和畸变系数。 如果您不知道如何校准您的相机,您可以查看 calibrateCamera ()
函数和 OpenCV 的校准教程。 您还可以使用 ArUco 模块校准相机,如 ArUco 和 ChArUco。
最后,校准后得到的是相机矩阵\(K\): 一个由3x3元素组成的矩阵,其中包括焦距和相机中心坐标(又称内参数) ,以及畸变系数: 一个由5个或更多元素组成的矢量,用于模拟相机产生的畸变
当你用 ArUco Marker估计姿势时,你可以单独估计每个Marker的姿势。 如果你想从一组Marker中估计一个姿势,使用 ArUco Boards (参见 ArUco Boards 的检测教程)。 使用 ArUco 板代替单一Marker允许一些Marker被遮挡。
4.1. 原理
相机的姿势是指从Marker坐标系到相机坐标系的3d转换。它是通过旋转和平移向量指定的(主要使用solvePnP()
函数)。
4.2. 核心函数cv::aruco::estimatePoseSingleMarkers()
1 | cv::Mat cameraMatrix, distCoeffs; |
- 第一个参数
markerCorners
是由detectMarkers()
函数返回的marker的4个角点的坐标vector - 第二个参数是marker的尺寸,单位是米或其他,估计出来的姿态的平移量将会与这个尺度保持一致,如果size使用(米),那么估计出来的平移量也是(米)
- 第三个参数是相机的内参矩阵
- 第四个参数是相机的畸变参数
- rvecs,tvecs是输出的位姿估计(旋转量,平移量),需要注意的是,旋转量是轴角表示的旋转,需要使用罗德里格斯公式转换为旋转矩阵R
这个函数所假定的Marker坐标系原点是Marker的中心,z 轴指向外面,如下图所示。轴色对应为
- x: 红色
- y: 绿色
- z: 蓝色
模块提供了一个绘制轴的功能,如上图所示,因此可以检查位姿估计,可视化代码如下:
1 | inputImage.copyTo(outputImage); |
- 函数的最后一个参数: (这里填了0.1) 指的是绘制的坐标轴的长度,与上面位姿估计的尺度保持一致
4.3. 代码
1 |
|
实际运行效果