Расстояние до объекта с помощью стереокамеры - PullRequest
13 голосов
/ 05 июня 2011

Есть ли способ рассчитать расстояние до конкретного объекта с помощью стереокамеры? Есть ли уравнение или что-то, чтобы получить расстояние, используя диспаратность или угол?

Ответы [ 3 ]

34 голосов
/ 06 июня 2011

ПРИМЕЧАНИЕ: Все описанное здесь можно найти в книге Learning OpenCV в главах о калибровке камеры и стереозрении.Вы должны прочитать эти главы, чтобы лучше понять шаги, описанные ниже.

Один из подходов, который не требует, чтобы вы измеряли все внутренние и внешние параметры камеры, - это использование функций калибровки openCVs.Внутренние характеристики камеры (искажение / перекос объектива и т. Д.) Можно рассчитать с помощью cv :: calibrateCamera, а внешние характеристики (соотношение между левой и правой камерой) можно рассчитать с помощью cv :: stereoCalibrate.Эти функции принимают количество точек в пиксельных координатах и ​​пытаются сопоставить их с координатами объекта реального мира.У CV есть отличный способ получить такие очки, распечатать черно-белую шахматную доску и использовать функции cv :: findChessboardCorners / cv :: cornerSubPix, чтобы извлечь их.Подходит около 10-15 пар изображений на шахматных досках.

Матрицы, рассчитанные с помощью функций калибровки, могут быть сохранены на диск, поэтому вам не придется повторять этот процесс при каждом запуске приложения.Здесь вы получите несколько аккуратных матриц, которые позволят вам создать карту выпрямления (cv :: stereoRectify / cv :: initUndistortRectifyMap), которую позже можно будет применить к вашим изображениям с помощью cv :: remap.Вы также получите аккуратную матрицу под названием Q, которая представляет собой матрицу несоответствия глубине.

Причина исправления ваших изображений заключается в том, что после завершения процесса для пары изображений (при условии, что калибровка выполнена правильно)каждый пиксель / объект на одном изображении можно найти в той же строке на другом изображении.

Есть несколько способов, с помощью которых вы можете перейти отсюда, в зависимости от того, какие функции выищите в изображении.Одним из способов является использование функций стерео соответствия CV, таких как Stereo Block Matching или Semi Global Block Matching.Это даст вам карту диспаратности для всего изображения, которую можно преобразовать в трехмерные точки с использованием матрицы Q (cv :: reprojectImageTo3D).

Недостатком этого является то, что, если в изображении не содержится много текстурной информацииCV на самом деле не очень хорош в построении плотной карты диспаратности (вы получите пробелы в ней, где она не сможет найти правильную диспаратность для данного пикселя), поэтому другой подход - найти точки, которые вы хотите сопоставить себе.Скажем, вы найдете объект / объект в x = 40, y = 110 на левом изображении и x = 22 на правом изображении (поскольку изображения выпрямлены, они должны иметь одинаковое значение y).Расхождение вычисляется как d = 40 - 22 = 18.

Построить cv :: Point3f (x, y, d), в нашем случае (40,110,18).Аналогичным образом найдите другие интересные точки, затем отправьте все точки в cv ::спективное преобразование (с матрицей Q в качестве матрицы преобразования, по сути, эта функция называется cv :: reprojectImageTo3D, но для разреженных карт диспаратности), и на выходе будут отображаться точкиXYZ-система координат с левой камерой в центре.

6 голосов
/ 05 июня 2011

Я все еще работаю над этим, поэтому пока не буду публиковать весь исходный код. Но я дам вам концептуальное решение.

Вам понадобятся следующие данные как входные данные (для обеих камер):

  • положение камеры
  • достопримечательность камеры (точка, на которую смотрит камера)
  • разрешение камеры (по горизонтали и вертикали)
  • угол обзора камеры (по горизонтали и вертикали)

Вы можете измерить последний самостоятельно, поместив камеру на лист бумаги и нарисовав две линии и измерив угол между этими линиями.

Камеры не должны быть выровнены каким-либо образом, вам нужно только видеть ваш объект в обеих камерах.

Теперь вычислите вектор от каждой камеры до вашего объекта. У вас есть (X, Y) пиксельные координаты объекта от каждой камеры, и вам нужно вычислить вектор (X, Y, Z). Обратите внимание, что в простом случае, когда объект виден прямо посередине камеры, решение будет просто (camera.PointOfInterest - camera.Position).

Как только оба вектора будут направлены на вашу цель, линии, определяемые этими векторами, должны пересекаться в одной точке в идеальном мире. В реальном мире они не будут из-за небольших ошибок измерений и ограниченного разрешения камер. Поэтому используйте ссылку ниже, чтобы рассчитать вектор расстояния между двумя линиями.

Расстояние между двумя линиями

В этой ссылке: P0 - ваша первая позиция кулачка, Q0 - ваша вторая позиция кулачка, а u и v - векторы, начинающиеся с положения камеры и указывающие на вашу цель.

Вас не интересует фактическое расстояние, они хотят рассчитать. Вам нужен вектор Wc - мы можем предположить, что объект находится в середине Wc. Как только у вас есть положение вашего объекта в трехмерном пространстве, вы также получаете любое расстояние, которое вам нравится.

Скоро выложу весь исходный код.

2 голосов
/ 13 июня 2011

У меня есть исходный код для обнаружения человеческого лица, и он возвращает не только глубину, но и координаты реального мира, когда левая камера (или правая камера, я не помню,) является исходной. Он адаптирован из исходного кода "Learning OpenCV" и ссылается на некоторые веб-сайты, чтобы заставить его работать. Результат, как правило, довольно точный.

...