基于ArUco标记的坐标转换

本教程展示了如何估计ArUco标记的位姿并使用4x4齐次变换矩阵将点云转换到ArUco标记坐标系。

小技巧

Zivid calibration board 包含了一个 ArUco 标记。

本教程使用了下图中显示的ArUco标记的点云。

ArUco标记的2D图像

我们可以在Zivid Studio中打开 原始点云 并进行检查。

备注

原始点云在 Sample Data(示例数据) 中。

现在,我们可以将深度视图中的Z范围设置为540毫米至735毫米。我们可以看到标记在大约570毫米的距离处,并且相机和标记框之间存在一个角度。

相机坐标系中的ArUco标记

首先,我们加载一个ArUco标记的点云。

跳转到源码

source

const auto arucoMarkerFile = std::string(ZIVID_SAMPLE_DATA_DIR) + "/CalibrationBoardInCameraOrigin.zdf";
std::cout << "Reading ZDF frame from file: " << arucoMarkerFile << std::endl;
const auto frame = Zivid::Frame(arucoMarkerFile);
auto pointCloud = frame.pointCloud();

由于我们使用的是OpenCV,我们需要将2D图像转换为OpenCV的图像格式。

跳转到源码

source

std::cout << "Converting to OpenCV image format" << std::endl;
const auto bgraImage = pointCloudToColorBGRA(pointCloud);
const auto grayImage = colorBGRAToGray(bgraImage);

然后我们将配置ArUco标记。

跳转到源码

source

std::cout << "Configuring ArUco marker" << std::endl;
const auto markerDictionary = cv::aruco::getPredefinedDictionary(cv::aruco::DICT_4X4_100);
std::vector<int> markerIds;
std::vector<std::vector<cv::Point2f>> markerCorners;
cv::Ptr<cv::aruco::DetectorParameters> detectorParameters = cv::aruco::DetectorParameters::create();
detectorParameters->cornerRefinementMethod = cv::aruco::CORNER_REFINE_SUBPIX;

接下来我们需要检测出2D图像中的ArUco标记并显示它。

跳转到源码

source

std::cout << "Detecting ArUco Marker" << std::endl;
cv::aruco::detectMarkers(grayImage, markerDictionary, markerCorners, markerIds, detectorParameters);

std::cout << "Displaying detected ArUco marker" << std::endl;
cv::Mat bgr;
cv::cvtColor(bgraImage, bgr, cv::COLOR_BGRA2BGR);
cv::aruco::drawDetectedMarkers(bgr, markerCorners);
displayBGR(bgr, "ArucoMarkerDetected");

然后我们估计 ArUco 标记的位姿。

跳转到源码

source

std::cout << "Estimating pose of detected ArUco marker" << std::endl;
const auto transformMarkerToCamera = estimateArUcoMarkerPose(pointCloud, markerCorners[0]);
std::cout << "Camera pose in ArUco marker frame:" << std::endl;
std::cout << transformMarkerToCamera << std::endl;
const auto transformCameraToMarker = transformMarkerToCamera.inverse();

最后,我们将点云转换到ArUco标记坐标系,并将转换后的点云保存到磁盘。

跳转到源码

source

std::cout << "Transforming point cloud from camera frame to ArUco marker frame" << std::endl;
pointCloud.transform(transformCameraToMarker);
std::cout << "Saving transformed point cloud to file: " << arucoMarkerTransformedFile << std::endl;
frame.save(arucoMarkerTransformedFile);

提示

了解更多关于 位置、方向和坐标变换

现在我们可以在Zivid Studio中打开 转换后的点云 进行检查。

备注

在Zivid Studio中缩小显示图像以查找数据,因为视点原点不适合观察转换后的点云。

我们现在可以在深度视图中手动将Z范围设置为-35mm至1mm,这样我们就可以过滤掉除了标定板和它旁边的物体之外的所有数据。这使我们可以看到我们在标定板上具有相同的Z值,并且从颜色渐变中我们可以检查该值是否为0。这意味着点云的原点位于ArUco标记上。

相机坐标系中的ArUco标记