Fork me on GitHub

opencv之ArucoMarker使用

background

aruco marker是一种类似于二维码的标记, 可以通过输入marker的尺寸, 检测图像中的marker计算处marker在相机坐标系中的3D位置.


在opencv中有aruco 库, 可以通过调用该库实现生成marker, 检测marker, 计算pose等功能.

#include <opencv2/aruco.hpp> 

Marker Creation

#include <opencv2/aruco.hpp> 
#include <opencv2/highgui.hpp>

int main(int argc, char** argv)
{
  // generate marker
  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);
  
  // store marker
  std::string out_file_name = "/home/liuzhiyang/test/marker.png";
  cv::imwrite(out_file_name, markerImage);
  return 0;
}

drawMarker函数的参数:

  • 第一个参数为字典
  • 第二个参数为marker id
  • 第三个参数为marker size
  • 第四个参数为输出的图像
  • 第五个参数为marker黑边的宽度, 默认为1.

Marker Detection

检测图像中marker的位置和id, 存储到vector中.

// detect markers
std::vector<int> v_marker_id;
std::vector<std::vector<cv::Point2f> > v_marker_corner;
cv::Ptr<cv::aruco::Dictionary> dictionary = cv::aruco::getPredefinedDictionary(cv::aruco::DICT_ARUCO_ORIGINAL);
cv::aruco::detectMarkers(input_image, dictionary, v_marker_corner, v_marker_id);

// draw marker
cv::Mat output_image = input_image.clone();
cv::aruco::drawDetectedMarkers(output_image, v_marker_corner, v_marker_id);

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

注: DICT_ARUCO_ORIGINAL: 为DICT_5X5_1024

Pose Estimation

估计marker在相机坐标系中的3D位姿, 需要知道相机的内参和畸变系数和marker的尺寸, 输出为marker坐标系到相机坐标系的变换R, t

// estimate marker pose(marker coordination to camera coordination)
cv::Mat camera_mat;
cv::Mat dist_coeff;
std::vector<cv::Vec3d>& v_rot;
std::vector<cv::Vec3d>& v_trans;
cv::aruco::estimatePoseSingleMarkers(v_marker_corner, marker_size, camera_mat, dist_coeff, v_rot, v_trans);

// draw axis
// draw marker axis
for (size_t i = 0; i < v_rot.size(); ++i)
{
  cv::aruco::drawAxis(output_image, camera_mat, dist_coeff, v_rot[i], v_trans[i], 0.2);
}
  • marker坐标系

    注: marker坐标系用marker的位置有关, z轴向外.

Selecting a dictionary

aruco模块中提供了多种字典类供使用, 在选择字典时需要注意, 选择与使用marker数量相近的字典, 比如说实例中使用了10个marker, 那么选择与10最接近且大于10的字典, 这样检测更加鲁棒.

  • Predefined dictionaries
cv::Ptr<cv::aruco::Dictionary> dictionary = cv::aruco::getPredefinedDictionary(cv::aruco::DICT_6X6_250);

参数为marker的size和字典中marker的数量.

From all the provided dictionaries, it is recommended to choose the smaller one that fits to your application. For instance, if you need 200 markers of 6x6 bits, it is better to use DICT_6X6_250 than DICT_6X6_1000. The smaller the dictionary, the higher the inter-marker distance.

reference

https://docs.opencv.org/3.1.0/d5/dae/tutorial_aruco_detection.html

posted @ 2021-06-26 15:53  chrislzy  阅读(2757)  评论(0编辑  收藏  举报