0

(在 iOS 中)我需要确定到可以旋转的基准标记的距离。

我正在使用 Aruco 库,到目前为止,我已经在 iOS 中实现了标记检测和姿势估计,但我真正需要的是相机到该标记的距离。

我已经看到一些示例,您使用标记的实际大小、相机的焦距和标记的屏幕尺寸来计算距离,但这并没有考虑应用于标记的任何旋转。

由于我有姿势估计工作,我“猜测”应该可以取消旋转标记的角点,然后使用这些点的边界框,以及实际尺寸和相机焦距。虽然我不完全确定这是正确的,或者如何实现它。

这是我第一次使用 OpenCV,所以我现在只是在猜测。

非常感谢任何和所有帮助。

非常感谢

4

1 回答 1

0

我在我的项目中使用下面的代码来检测相机和标记之间的 Z 距离。我不确定它是否完全正确,但它给出了可接受的结果。

Ptr<aruco::DetectorParameters> detectorParams = aruco::DetectorParameters::create();
detectorParams->doCornerRefinement = true;

Ptr<aruco::Dictionary> dictionary = aruco::getPredefinedDictionary(aruco::PREDEFINED_DICTIONARY_NAME(kMarkerDictionaryID));

Mat camMatrix, distCoeffs;

if (!readCameraParameters(kCameraParametersFile, camMatrix, distCoeffs)) {
    
    // ...
    
    return;
}

VideoCapture inputVideo;
inputVideo.open(kCameraID);

while (inputVideo.grab()) {
    
    Mat image;
    
    inputVideo.retrieve(image);
    
    vector< int > ids;
    vector< vector< Point2f > > corners;
    vector< Vec3d > rvecs, tvecs;
    
    aruco::detectMarkers(image, dictionary, corners, ids, detectorParams);
    
    if (ids.size() > 0) {
        
        aruco::estimatePoseSingleMarkers(corners, kMarkerLengthInMeters, camMatrix, distCoeffs, rvecs, tvecs);
        
        for (unsigned int i = 0; i < ids.size(); i++) {
            
            // if (ids[i] != kMarkerID)
            //     continue;
                            
            // Calc camera pose
            Mat R;
            Rodrigues(rvecs[i], R);
            Mat cameraPose = -R.t() * (Mat)tvecs[i];

            double x = cameraPose.at<double>(0,0);
            double y = cameraPose.at<double>(0,1);
            double z = cameraPose.at<double>(0,2);

            // So z is the distance between camera and marker 

            // Or if you need rotation invariant offsets
            // x = tvecs[i][0];
            // y = tvecs[i][0];
            // z = tvecs[i][0];

            cout << "X: " << x << " Y: " << y << " Z: " << z << endl;

            aruco::drawAxis(image, camMatrix, distCoeffs, rvecs[i], tvecs[i], kMarkerLengthInMeters * 0.5f);
        }

        aruco::drawDetectedMarkers(image, corners, resultIds);
    }
    
    resize(image, image, Size(image.cols / 2, image.rows / 2));
    imshow("out", image);
    char key = (char)waitKey(kWaitTimeInmS);
    if (key == 27) break;
}

于 2017-02-26T13:36:32.340 回答