You're viewing an old version of the documentation. Click here to see the latest release.

基于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标记