В настоящее время я работаю над 3d-реконструкцией рентгеновских изображений, и поэтому мне нужно стереоформировать изображения двух видов, прежде чем я смогу сопоставить некоторые функции с помощью эпилинов. Я использую OpenCV 2.4 с C++.OpenCV Стерео выпрямление из созданных вручную матриц
Для этой цели я получил набор пар рентгеновских изображений (рентгеновские снимки с конусным лучом, без реальных камер с параметрами искажения или реальное фокусное расстояние), один из передне-заднего вида (прямо глядя на сундук), и один с бокового вида (смотрящий на сундук сбоку). Я знаю некоторые параметры, такие как виртуальное фокусное расстояние (равное для обоих представлений), которое я могу использовать, и изображения имеют разрешение 512x512 пикселей, поэтому проекция камеры на изображения составляет (255,255) для обоих видов. Также я знаю, что камеры перпендикулярны. Из этой информации я разработал матрицу поворота R и вектор трансляции t (оба проверены с помощью 3d-графика в Matlab).
Задача: R и t на самом деле достаточно для стерео выпрямления в OpenCV, но результирующие изображения после исправления являются черными. Googling привел меня к ошибке в stereoRectify, но я сомневаюсь, что это ошибка, так как я могу запустить пример OpenRV, который работает. При попытке стереореформирования в 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.
Я был бы рад, если бы кто-нибудь мог мне помочь, я застрял в этой проблеме уже несколько недель. Большое спасибо!
Вы пробовали разные значения для параметра 'alpha'? В вашем опубликованном коде 'alpha' равен 1. Пробовал ли вы 0? Из opencv docs 'stereoRectify': *' alpha = 0' означает, что выпрямленные изображения масштабируются и сдвигаются так, что видны только действительные пиксели (без выпрямления черных областей) * –