关于 stereoCalibrate error with OutputArray::Create assertion error 的汇编解释

Assembly explanation about stereoCalibrate error with OutputArray::Create assertion error

我在 Opencv 2.4.11 中执行 stereoCalibrate 时遇到错误,即:

OpenCV Error: Assertion failed (!fixedSize() || ((Mat*)obj)->size.operator()() == Size(cols, rows)) in cv::_OutputArray::create,

我认为这一定是这些参数之间存在一些大小错误,这些参数一一通过它们。但是还是有错误。我希望很棒的人可以从下面的汇编代码中找到错误。这是我的代码中的方法调用。

double error = cv::stereoCalibrate(
        objPoints, cali0.imgPoints, cali1.imgPoints,
        camera0.intr.cameraMatrix, camera0.intr.distCoeffs,
        camera1.intr.cameraMatrix, camera1.intr.distCoeffs,
        cv::Size(1920,1080), m.rvec, m.tvec, m.evec, m.fvec,
        cv::TermCriteria(CV_TERMCRIT_ITER + CV_TERMCRIT_EPS, 100, 1e-5)
        ,CV_CALIB_FIX_INTRINSIC + CV_CALIB_USE_INTRINSIC_GUESS
    );

在我的代码中,m.rvec是(3,3,CV_64F),m.tvec是(3,1,CV_64F),m.evec和 m.fvec 未预先分配,这与 stereoCalibrate 示例相同。 intr.cameraMatrix 是 (3,3,CV_64F) 并且 intr.distCoeffs 是 (8,1,CV_64F),objPoints 是从存储角的 3d 位置的棋盘格计算的点的所有 z 值都为零。

阅读@Josh 的建议后,我将代码修改为 CV_64F 中的普通输出 mat 对象,但它仍然抛出此断言。

cv::Mat R, t, e, f;
    double error = cv::stereoCalibrate(
        objPoints, cali0.imgPoints, cali1.imgPoints,
        camera0.intr.cameraMatrix, camera0.intr.distCoeffs,
        camera1.intr.cameraMatrix, camera1.intr.distCoeffs,
        cali0.imgSize, R, t, e, f,
        cv::TermCriteria(CV_TERMCRIT_ITER + CV_TERMCRIT_EPS, 100, 1e-5));

最后我解决了这个问题,提醒一下,确保你传入的相机参数不是const类型....

为什么要去组装? OpenCV 是开源的,您可以在此处查看调用的代码:https://github.com/opencv/opencv/blob/master/modules/calib3d/src/calibration.cpp#L3523

如果您在 OpenCV 中断言失败,通常是因为您传递了一个形状不正确的矩阵。 OpenCV 非常挑剔。断言失败是在 OutputArray 上,因此检查函数签名有四种可能的罪魁祸首:

OutputArray _Rmat, OutputArray _Tmat, OutputArray _Emat, OutputArray _Fmat

尺寸调整在 cv::stereoCalibrate 内部完成:

https://github.com/opencv/opencv/blob/master/modules/calib3d/src/calibration.cpp#L3550

_Rmat.create(3, 3, rtype);
_Tmat.create(3, 1, rtype);

<-- snipped -->

if( _Emat.needed() )
{
    _Emat.create(3, 3, rtype);
    p_matE = &(c_matE = _Emat.getMat());
}
if( _Fmat.needed() )
{
    _Fmat.create(3, 3, rtype);
    p_matF = &(c_matF = _Fmat.getMat());

}

在这些调用之一中触发断言,代码在这里:

https://github.com/opencv/opencv/blob/master/modules/core/src/matrix.cpp#L2241

尝试传入普通 Mat 对象而不预先分配它们的形状。