我目前正在对 X 射线图像进行 3D 重建,因此我需要先对两个视图的图像进行立体校正,然后才能在外延线的帮助下匹配某些特征。我正在使用带有 C++ 的 OpenCV 2.4。
为此,我得到了一组 X 射线图像(锥形束 X 射线图像,没有具有失真参数或真实焦距的真实相机),一个来自前后视图(直接看胸部),另一个从侧面看(从侧面看胸部)。我知道一些参数,例如我可以使用的虚拟焦距(两个视图相等),并且图像的分辨率为 512x512px,因此两个视图的图像上的相机投影都为 (255,255)。我也知道相机是垂直的。根据这些信息,我开发了一个旋转矩阵 R 和一个平移向量 t(两者都在 Matlab 中的 3d 图的帮助下进行了验证)。
问题:在 OpenCV 中,R 和 t 实际上足以进行立体校正,但校正后的结果图像是黑色的。谷歌搜索让我发现了 stereoRectify 中的一个错误,但我怀疑这是错误,因为我可以运行 OpenCV stereoRectification 示例,它确实有效。在 Matlab 中尝试立体校正时,我至少可以看到一些失真的校正结果。
这是我的 C++ 代码:
float camera_matrix_ap_data[] = {1207*2.0, 0.0, 255.0,
0.0, 1207*2, 255.0,
0.0, 0.0, 1.0};
cv::Mat camera_matrix_ap(3, 3, CV_64F, camera_matrix_ap_data);
float camera_matrix_lat_data[] = {1207*2, 0.0, 255.0,
0.0, 1207*2, 255.0,
0.0, 0.0, 1.0};
cv::Mat camera_matrix_lat(3, 3, CV_64F, camera_matrix_lat_data);
///
/// @brief the distortion matrices
///
cv::Mat distortion_ap(4, 1, CV_64F, 0.0);
cv::Mat distortion_lat(4, 1, CV_64F, 0.0);
///
/// @brief Translation and Rotation matrices
///
float R_data[] = {0.0, 0.0, 1.0,
0.0, 1.0, 0.0,
-1.0, 0.0, 0.0};
float T_data[] = {-(1207.0*2 + 255), 0.0, 1207.0*2 + 255};
cv::Mat R(3, 3, CV_64F, R_data);
cv::Mat T(3, 1, CV_64F, T_data);
for (int i=1; i<=20; i++) {
std::stringstream filenameAP_tmp;
std::stringstream filenameLAT_tmp;
filenameAP_tmp << "imageAP"<< i <<".jpg";
filenameAP = filenameAP_tmp.str();
filenameLAT_tmp << "imageLAT"<< i <<".jpg";
filenameLAT = filenameLAT_tmp.str();
rectimg_ap = cv::imread(filenameAP);
rectimg_lat = cv::imread(filenameLAT);
// Yes, these images are grayscale
/// Experimental
/// Stereo rectify both images
cv::Mat R1(3, 3, CV_64F);
cv::Mat R2(3, 3, CV_64F);
cv::Mat P1(3, 4, CV_64F);
cv::Mat P2(3, 4, CV_64F);
cv::Mat Q(4, 4, CV_64F);
cv::Rect validRoi[2];
// buggy?
cv::stereoRectify(camera_matrix_ap, distortion_ap, camera_matrix_lat, distortion_lat, rectimg_ap.size(), R, T, R1, R2, P1, P2, Q, CALIB_ZERO_DISPARITY, 1, rectimg_ap.size(), &validRoi[0], &validRoi[1] );
// Maps for AP View
cv::Mat map1x(rectimg_ap.size(), CV_32FC1, 255.0);
cv::Mat map2x(rectimg_ap.size(), CV_32FC1, 255.0);
// Maps for LAT View
cv::Mat map1y(rectimg_ap.size(), CV_32FC1, 255.0);
cv::Mat map2y(rectimg_ap.size(), CV_32FC1, 255.0);
cv::initUndistortRectifyMap(camera_matrix_ap, distortion_ap, R1, P1, rectimg_ap.size(), CV_32FC1, map1x, map1y);
cv::initUndistortRectifyMap(camera_matrix_lat, distortion_lat, R2, P2, rectimg_lat.size(), CV_32FC1, map2x, map2y);
cv::Mat tmp1, tmp2;
cv::remap(rectimg_ap, tmp1, map1x, map1y, INTER_LINEAR);
cv::remap(rectimg_lat, tmp2, map2x, map2y, INTER_LINEAR);
//findHomography(rectimg_ap, rectimg_lat, CV_RANSAC);
}
所以我想知道这段代码或我的矩阵有什么问题,因为重新映射后的校正图像完全是黑色的。OpenCV和Matlab之间的坐标系轴有区别吗?正如我所读到的,在 OpenCV 中,z 轴指向图像平面,Matlab 也是如此。
如果有人可以帮助我,我会很高兴,我已经被这个问题困扰了好几个星期了。非常感谢!