opencv 基于手眼标定的非重叠多摄像机标定

rn0zuynd  于 2022-11-24  发布在  其他
关注(0)|答案(2)|浏览(220)

多摄像机重叠视图的校准是很简单的。然而,我想校准一个多摄像机没有重叠视图的装备,这是背靠背的。我看了一些资源,发现opencv的手眼校准似乎解决了我的问题。
为了验证我的想法,我假设了一个简单的案例,我使用手眼校准来校准立体摄像机设置。在我的设置中,两个摄像机构建一个装备,并面向同一个aruco板。我的目标是找到两个摄像机之间的外在。
根据OpenCV文档,我创建了如下输入:
左摄像机;基板-〉aruco板;目标-〉相同板;摄像机-〉右摄像机;可以使用aruco::estimatePoseBoard()来计算board 2leftCam或board 2 rightCam
程序:

R_gripper2base -> board2leftCam.inv();
R_target2cam -> board2rightCam.
R_cam2gripper -> right2left.

输出应该是cam 2gripper-〉右摄像机到左摄像机。但是结果与立体校准非常不同。
为什么我的校准结果是错误的?提前感谢!
我的代码:

/*
* R_lefCam2Board  => R_gripper2base
*/
std::vector<cv::Mat> rvecMat_lefCam2Board, tvecMat_lefCam2Board;
for (size_t i = 0; i < lefCamfilenames.size(); ++i) {
    cv::Mat matLef = cv::imread(lefCamfilenames[i]);
    vector<int> ids;
    vector<vector<Point2f>> corners, rejected;
    aruco::detectMarkers(matLef, dictionary, corners, ids, params, rejected);
    cv::Vec3d rvec, tvec; // from floor 2 bot camera
    aruco::estimatePoseBoard(corners, ids, board, botCam.mtx, botCam.dist, rvec, tvec);
    cv::Mat pose = vec3d2Mat44(rvec, tvec); // pose is double
    cv::Mat pose_inv = pose.inv();
    pose_inv.convertTo(pose_inv, CV_32F);

    cv::Mat R_lefCam2Board, T_lefCam2Board;
    mat44ToRT_(pose_inv, R_lefCam2Board, T_lefCam2Board);
    rvecMat_lefCam2Board.push_back(R_lefCam2Board);
    tvecMat_lefCam2Board.push_back(T_lefCam2Board);
}
/*
 * R_Board2botCam  => R_target2cam
 */
std::vector<cv::Mat> rvecMat_board2botCam, tvecMat_board2botCam;
for (size_t i = 0; i < botCamfilenames.size(); ++i) {
    cv::Mat matBot = cv::imread(botCamfilenames[i]);
    vector<int> ids;
    vector<vector<Point2f>> corners, rejected;
    aruco::detectMarkers(matBot, dictionary, corners, ids, params, rejected);
    cv::Vec3d rvec, tvec; // from floor 2 bot camera
    aruco::estimatePoseBoard(corners, ids, board, botCam.mtx, botCam.dist, rvec, tvec);
    cv::Mat pose = vec3d2Mat44(rvec, tvec); // pose is double
    pose.convertTo(pose, CV_32F);

    cv::Mat R_bot2floor, T_bot2floor;
    mat44ToRT_(pose_inv, R_bot2floor, T_bot2floor);
    rvecMat_board2botCam.push_back(R_bot2floor);
    tvecMat_board2botCam.push_back(T_bot2floor);
}
/*
* Calculate result R_Bot2Left  => R_cam2gripper
*/
cv::Mat R_bot2lef, T_bot2lef;
cv::calibrateHandEye(rvecMat_lefCam2Board, tvecMat_lefCam2Board,
                     rvecMat_board2botCam, tvecMat_board2botCam,
                     R_bot2lef, T_bot2lef);
ejk8hzay

ejk8hzay1#

要在不重叠视图的情况下外部校准多个摄像机(即,找到它们相对于彼此的位置和方向),您需要在所有摄像机中观察一个公共参考对象(也称为“校准目标”),或一组已知形状、位置和方向的对象m。
这可以通过以下几种方式实现:

  • 有一个固定的物体,一次只能在一个摄像机中观察到,然后用已知的运动来移动装置,使物体依次在每个摄像机中可见。例如:安装在转台上的摄像机,转台旋转以向每个摄像机“呈现”校准目标。
  • 物体是一个固定的物体,足够大,可以在所有摄像机中观察到它的不同部分,并且这些部分之间的几何关系是已知的。所有摄像机都观察夜空,并且所观察的星点/星座的星历表是已知的。

关键是,你需要在所有图像中“看到”“一些东西”,从中你可以推断出摄像机的方向和位置,而这个东西必须以一种能够将这些位置和方向相互关联的方式出现在摄像机中。

vwoqyblh

vwoqyblh2#

如果在没有重叠视野的情况下出现摄像机校准问题,则可以使用

CALICO基于与您尝试的方法类似的方法。他们首先使用手眼校准来确定姿势的粗略估计,然后使用带有重投影误差的光束调整来进行微调。

相关问题