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

Другие вопросы по тегам