如果你从图像中提取了特征点,例如使用关键点检测算法(如SIFT、SURF、ORB等),并且这些特征点在两个视图中都能够被检测到,你可以使用双目视觉标定的结果将这些特征点映射到世界坐标中。

#include <opencv2/opencv.hpp>
#include <iostream>

int main() {
    // 读取双目标定的结果
    cv::FileStorage fs("stereo_calibration.yml", cv::FileStorage::READ);

    cv::Mat cameraMatrix1, distCoeffs1, cameraMatrix2, distCoeffs2, R, T, E, F;
    fs["cameraMatrix1"] >> cameraMatrix1;
    fs["distCoeffs1"] >> distCoeffs1;
    fs["cameraMatrix2"] >> cameraMatrix2;
    fs["distCoeffs2"] >> distCoeffs2;
    fs["R"] >> R;
    fs["T"] >> T;
    fs.release();

    // 读取左右摄像头的图像
    cv::Mat imgLeft = cv::imread("left_image.jpg", cv::IMREAD_GRAYSCALE);
    cv::Mat imgRight = cv::imread("right_image.jpg", cv::IMREAD_GRAYSCALE);

    // 矫正图像
    cv::Mat imgRectLeft, imgRectRight;
    cv::remap(imgLeft, imgRectLeft, cameraMatrix1, distCoeffs1, cv::INTER_LINEAR);
    cv::remap(imgRight, imgRectRight, cameraMatrix2, distCoeffs2, cv::INTER_LINEAR);

    // 使用ORB特征点检测
    cv::Ptr<cv::ORB> orb = cv::ORB::create();
    std::vector<cv::KeyPoint> keypointsLeft, keypointsRight;
    cv::Mat descriptorsLeft, descriptorsRight;

    orb->detectAndCompute(imgRectLeft, cv::noArray(), keypointsLeft, descriptorsLeft);
    orb->detectAndCompute(imgRectRight, cv::noArray(), keypointsRight, descriptorsRight);

    // 使用暴力匹配寻找匹配的特征点对
    cv::BFMatcher matcher(cv::NORM_HAMMING);
    std::vector<cv::DMatch> matches;
    matcher.match(descriptorsLeft, descriptorsRight, matches);

    // 提取匹配点对的像素坐标
    std::vector<cv::Point2f> imgPointsLeft, imgPointsRight;
    for (const auto& match : matches) {
        imgPointsLeft.push_back(keypointsLeft[match.queryIdx].pt);
        imgPointsRight.push_back(keypointsRight[match.trainIdx].pt);
    }

    // 使用三角测量将像素坐标转换为世界坐标
    cv::Mat points4D;
    cv::triangulatePoints(cameraMatrix1 * cv::Mat::eye(3, 4, CV_64F), cameraMatrix2 * cv::Mat::eye(3, 4, CV_64F),
                          imgPointsLeft, imgPointsRight, points4D);

    // 转换为齐次坐标并获取三维坐标
    cv::Mat points3D;
    cv::convertPointsFromHomogeneous(points4D.t(), points3D);

    // 输出三维坐标
    for (int i = 0; i < points3D.rows; ++i) {
        cv::Point3f worldPoint = points3D.at<cv::Point3f>(i);
        std::cout << "World Coordinate " << i << ": " << worldPoint << std::endl;
    }

    return 0;
}
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值