对于我的雇主,我将已经实施的图像校正方法的结果与相应的OpenCV实现的结果进行比较。但是,一旦调用OpenCV函数,就会抛出异常。
OpenCV整改功能的标题是
void stereoRectify(InputArray cameraMatrix1, InputArray distCoeffs1,
InputArray cameraMatrix2, InputArray distCoeffs2,
Size imageSize, InputArray R, InputArray T, OutputArray R1,
OutputArray R2, OutputArray P1, OutputArray P2,
OutputArray Q, int flags=CALIB_ZERO_DISPARITY,
double alpha=-1, Size newImageSize=Size(),
Rect* validPixROI1=0, Rect* validPixROI2=0);
作为InputArray和OutputArray,我使用了
类型的对象cv::Mat
。由于已知摄像机的校准,因此我使用正确的值手动初始化输入矩阵。根据{{3}}:
,矩阵具有以下大小cv::Mat cameraMatrix1; // 3x3 matrix
cv::Mat distCoeffs1; // 5x1 matrix for five distortion coefficients
cv::Mat cameraMatrix2; // 3x3 matrix
cv::Mat distCoeffs2; // 5x1 matrix
cv::Mat R; // 3x3 matrix, rotation left to right camera
cv::Mat T; // 4x1 matrix, translation left to right proj. center
我初始化了这样的矩阵:
T = cv::Mat::zeros(4, 1, CV_64F);
T.at<double>(0, 0) = proj_center_right.x - proj_center_left.x;
T.at<double>(1, 0) = proj_center_right.y - proj_center_left.y;
T.at<double>(2, 0) = proj_center_right.z - proj_center_left.z;
对于所有矩阵,我使用CV_64F作为值类型。
我在控制台上打印了矩阵的内容,以验证是否正确设置了所有值(舍入):
cameraMatrix1:
| 6654; 0,1231 |
| 0; 6654; 1037 |
| 0; 0; 1 |distCoeffs1:
| -4.57e-009; 5.94e-017; 3.68e-008; -3.46e-008; 6.37e-023 |cameraMatrix2:
| 6689; 0,1249 |
| 0; 6689; 991 |
| 0; 0; 1 |distCoeffs2:
| -4.72e-009; 2.88e-016; 6.2E-008; -8.74e-008; -8.18e-024 |R:
| 0.87; -0.003,-0.46 |
| 0.001; 0.999; -0.003 |
| 0.46; 0.002; 0.89 |T:
| 228; 0; 0; 0 |
到目前为止,一切似乎都是正确的。此外,我将输出矩阵初始化为标识矩阵(使用cv :: Mat :: eye(...)),具有以下大小:
cv::Mat R1; // 3x3 matrix
cv::Mat R2; // 3x3 matrix
cv::Mat P1; // 3x4 matrix
cv::Mat P2; // 3x4 matrix
cv::Mat Q; // 4x4 matrix
最后,所需的cv :: Size对象设置为宽度2448和高度2050(摄像机获取的图像的大小)。一旦我将参数传递给OpenCV
cv::stereoRectify(cameraMatrix1, distCoeffs1, cameraMatrix2, distCoeffs2, imgSize, R, T, R1, R2, P1, P2, Q);
,程序崩溃了。控制台上的错误消息说明
opencv_core248,void cdecl cv :: error(class cv :: Exception const&amp; ptr64)+ 0x152(无效的帧指针)
由于所有矩阵和cv :: Size对象都被正确初始化,我没有看到,可能是错误的。对于任何建议,我很感激。
答案 0 :(得分:4)
您的代码最初在gemm()中崩溃,将T更改为3x1 vec似乎有所帮助:
// Mat_<double> used here for easy << initialization
cv::Mat_<double> cameraMatrix1(3,3); // 3x3 matrix
cv::Mat_<double> distCoeffs1(5,1); // 5x1 matrix for five distortion coefficients
cv::Mat_<double> cameraMatrix2(3,3); // 3x3 matrix
cv::Mat_<double> distCoeffs2(5,1); // 5x1 matrix
cv::Mat_<double> R(3,3); // 3x3 matrix, rotation left to right camera
cv::Mat_<double> T(3,1); // * 3 * x1 matrix, translation left to right proj. center
// ^^ that's the main diff to your code, (3,1) instead of (4,1)
cameraMatrix1 << 6654, 0, 1231, 0, 6654, 1037, 0, 0, 1;
cameraMatrix2 << 6689, 0, 1249, 0, 6689, 991, 0, 0, 1;
distCoeffs1 << -4.57e-009, 5.94e-017, 3.68e-008, -3.46e-008, 6.37e-023;
distCoeffs2 << -4.72e-009, 2.88e-016, 6.2e-008, -8.74e-008, -8.18e-024;
R << 0.87, -0.003, -0.46, 0.001, 0.999, -0.003, 0.46, 0.002, 0.89;
T << 228, 0, 0;
cv::Mat R1,R2,P1,P2,Q; // you're safe to leave OutpuArrays empty !
Size imgSize(3000,3000); // wild guess from you cameramat ( not that it matters )
cv::stereoRectify(cameraMatrix1, distCoeffs1, cameraMatrix2, distCoeffs2, imgSize, R, T, R1, R2, P1, P2, Q);
cerr << "Q" << Q << endl;