Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

OpenCV Stereo rectification from manually created matrices

I am currently working on a 3d reconstruction of X-Ray images, and therefore I need to stereo-rectify images of two views before I can match some features with help of the epilines. I am using OpenCV 2.4 with C++.

For this purpose I got a set of pairs of X-Ray images (cone beam X-ray images, no real cameras with distortion parameters or a real focal length), one from the anteroposterior view (directly looking at the chest), and one from the lateral view (looking at the chest from the side). I know some parameters like a virtual focal length (equal for both views) that I can use, and the images have got a resolution of 512x512px, hence the camera projection at the images is at (255,255) for both views. Also i know that the cameras are perpendicular. From this information I developed a rotation matrix R and a translation vector t (both verified with help of a 3d plot in Matlab).

Problem: R and t are actually enough for a stereo rectification in OpenCV, but the resulting images after rectification are black. Googling led me to a bug in stereoRectify, but I doubt that it is the bug as I can run the OpenCV stereoRectification example which does work. When trying a stereoRectification in Matlab I can at least see some distorted rectification results.

Here is my C++ code:

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);

}

So I am wondering what is wrong with this code or my matrices, as the rectification images after remap are completely black. Is there a difference concerning the coordinate system axes between OpenCV and Matlab? As I read, in OpenCV the z-axis points to the image plane, and it was the same for Matlab.

I'd be glad if someone could help me, I am stuck with this problem for weeks now. Thank you very much!

like image 251
bumuckl Avatar asked Nov 12 '13 09:11

bumuckl


1 Answers

Try changing the "float" variable types to "double". The CV_64F corresponds to a double, and not to a float, since it is 8 bytes (= 64bits). I tried your code with my own matrix values, and that did the trick.

like image 102
C.B. Avatar answered Oct 23 '22 01:10

C.B.