OpenCV Stereo Matching/ Калибровка
Первоначально я разместил это на форумах OpenCV, но, к сожалению, я не получил слишком много просмотров / ответов, поэтому я публикую здесь с надеждой, что кто-то может подсказать, пожалуйста, предложить?
Я использую стерео камеру Bumblebee XB3 и у нее 3 объектива. Я потратил около трех недель, читая форумы, учебные пособия, учебную книгу OpenCV и актуальную документацию OpenCV по использованию функции калибровки стерео и согласования стерео. Таким образом, моя проблема в том, что у меня есть хорошая карта диспаратности, но очень плохие облака точек, которые кажутся искаженными / сжатыми и не отражают фактическую сцену.
Что я сделал до сих пор:
Использовали примеры OpenCV Stereo_calibration и Stereo_matching, чтобы:
Откалибровал мою стерео камеру, используя изображения шахматной доски
1) Необработанные изображения сцены: http://answers.opencv.org/upfiles/1380850337241986.jpg
2) Исправлены необработанные изображения, полученные с камеры с использованием матриц после калибровки камеры
: http://answers.opencv.org/upfiles/13808502665723237.png
3) Генерация изображения несоответствия из выпрямленных изображений с использованием Stereo Matching (SGBM)
: 4) спроектировал эти различия в 3D Point Cloud
Что я сделал до устранения моей проблемы:
- Я попробовал 1-е и 2-е изображения, затем 2-й и 3-й объективы и, наконец, 1-й и 2-й.
- Я перезапустил калибровку снимков шахматной доски, изменив расстояние (ближе / дальше)
- Я использовал более 20 стереопар для калибровки
- Используемый размер шахматной доски: я использовал изображение шахматной доски 9x6 для калибровки и теперь переключился на использование изображения 8x5
- Я попытался использовать Block Matching, а также варианты SGBM и получить
относительно похожие результаты. Получение
лучшие результаты с SGBM до сих пор. - Я изменил диапазоны диспаратности, изменил размер окна SAD и т. Д. С небольшим улучшением
Я подозреваю, что проблема в следующем:
Мое изображение несоответствия выглядит относительно приемлемым, но следующий шаг - перейти к облаку 3D-точек с использованием матрицы Q. Я подозреваю, что я не калибрую камеры правильно, чтобы генерировать правильную матрицу Q. К сожалению, я ударился о стену, подумав, что еще я могу сделать, чтобы получить лучшую матрицу Q. Может кто-нибудь предложить, пожалуйста, пути вперед?
Другая вещь, которую я думаю, может быть проблематичной, это предположения, которые я делаю при использовании функции cv::stereoCalibrate. На данный момент я индивидуально откалибрую каждую камеру, чтобы получить матрицы камеры и искажения (cameraMatrix[0], distCoeffs[0] и cameraMatrix[1], distCoeffs[1]), так что это немного усложняет сложную функцию стереокалибровки.
stereoCalibrate(objectPoints, imagePoints[0], imagePoints[1],
cameraMatrix[0], distCoeffs[0],
cameraMatrix[1], distCoeffs[1],
imageSize, R, T, E, F,
TermCriteria(CV_TERMCRIT_ITER+CV_TERMCRIT_EPS, 100, 1e-5),
//CV_CALIB_FIX_ASPECT_RATIO +
//CV_CALIB_ZERO_TANGENT_DIST +
//CV_CALIB_SAME_FOCAL_LENGTH +
CV_CALIB_RATIONAL_MODEL
//CV_CALIB_FIX_K3 + CV_CALIB_FIX_K4 + CV_CALIB_FIX_K5
);
Кроме того, я думаю, что было бы полезно упомянуть, как я иду от неравенства к облаку точек. Я использую OpenCV cv::reprojectImageTo3D, а затем записываю данные в облачную структуру PCL Point. Вот соответствующий код:
cv::reprojectImageTo3D( imgDisparity16S, reconstructed3D, Q, false, CV_32F);
for (int i = 0; i < reconstructed3D.rows; i++)
{
for (int j = 0; j < reconstructed3D.cols; j++)
{
cv::Point3f cvPoint = reconstructed3D.at<cv::Point3f>(i, j);
//Filling in a PCL structure
pcl::PointXYZRGB point;
point.x = cvPoint.x;
point.y = cvPoint.y;
point.z = cvPoint.z;
point.rgb = rectified_imgRight.at<cv::Vec3b>(i,j)[0]; //Grey information
point_cloud_ptr->points.push_back (point);
}
}
point_cloud_ptr->width = (int) point_cloud_ptr->points.size();
point_cloud_ptr->height = 1;
pcl::io::savePCDFileASCII("OpenCV-PointCloud.pts", *point_cloud_ptr);
PS: причина, по которой я решил загрузить эти изображения, заключается в том, что сцена имеет некоторую текстуру, поэтому я ожидал ответа о том, что сцена слишком однородна. Чехол на перегородку и стул довольно богат с точки зрения текстуры.
Несколько вопросов:
Можете ли вы помочь мне удалить плоскость изображения / диспаратности, которая кажется частью облака точек? Почему это происходит?
Есть что-то очевидное, что я делаю неправильно? Я бы опубликовал свой код, но он очень похож на предоставленные примеры OpenCV, и я не думаю, что я делаю что-то более творчески. Я могу, если есть определенный раздел, который может касаться.
По моему наивному мнению, кажется, что несоответствие изображения в порядке. Но облако точек - это определенно то, чего я бы не ожидал от относительно приличного изображения несоответствия, оно НАМНОГО хуже.
Если это поможет, я упомянул Q-матрицу, которую я получаю после калибровки камеры, если что-то очевидное выпрыгивает. Сравнивая это с учебной книгой OpenCV, я не думаю, что есть что-то явно неверное...
Q: rows: 4
cols: 4
data: [ 1., 0., 0., -5.9767076110839844e+002, 0., 1., 0.,
-5.0785438156127930e+002, 0., 0., 0., 6.8683948509213735e+002, 0.,
0., -4.4965180874519222e+000, 0. ]
Спасибо за чтение, и я буду признателен за любые предложения на данный момент...
1 ответ
Я обнаружил аналогичные проблемы при использовании функции реконструкции 3D OpenCV (v.2.4.6). Некоторые люди, такие как Мартин Перис, снова реализовались сами. http://blog.martinperis.com/2012/01/3d-reconstruction-with-opencv-and-point.html
К сожалению, иногда я обнаружил проблемы в обеих реализациях с моими данными. Итак, я предположил, что моя проблема в этих случаях связана с плохим описанием параметров внешней камеры. Возможно, это тоже ваш случай.: -?
PS. Чтобы избавиться от фона, вам нужно его сегментировать. Или, по крайней мере, проверьте значения глубины, превышающие пороговое значение, после реконструкции. Флаг handleMissingValues удаляет только точки на "бесконечности" PS2. Пожалуйста, сообщите нам, если вы решите эту проблему. Я думаю, что это ценно для всего сообщества. Thnx