OpenCV Stereo выпрямление из созданных вручную матриц

В настоящее время я работаю над трехмерной реконструкцией рентгеновских изображений, и поэтому мне нужно стерео-выпрямить изображения двух видов, прежде чем я смогу сопоставить некоторые функции с помощью эпилинов. Я использую OpenCV 2.4 с C ++.

Для этой цели я получил набор пар рентгеновских изображений (рентгеновские снимки с коническим пучком, без реальных камер с параметрами искажения или реальным фокусным расстоянием), одну с переднезаднего вида (непосредственно смотря на грудь) и одну с бокового обзора (глядя на сундук сбоку). Я знаю некоторые параметры, такие как виртуальное фокусное расстояние (равное для обоих видов), которое я могу использовать, и изображения имеют разрешение 512×512 пикселей, следовательно, проекция камеры на изображениях составляет (255 255) для обоих видов. Также я знаю, что камеры перпендикулярны. Из этой информации я разработал матрицу вращения R и вектор перевода t (оба проверены с помощью трехмерного графика в Matlab).

Проблема: R и t на самом деле достаточно для стерео выпрямления в OpenCV, но результирующие изображения после выпрямления черные. Поиск в Google привел меня к ошибке в 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.

Я был бы рад, если бы кто-то мог помочь мне, я застрял с этой проблемой в течение нескольких недель. Большое спасибо!

6

Решение

Попробуйте изменить типы переменных «float» на «double». CV_64F соответствует double, а не float, так как он составляет 8 байтов (= 64 бита). Я попробовал ваш код с моими собственными значениями матрицы, и это помогло.

1

Другие решения

Других решений пока нет …