Подтвердить что ты не робот

OpenCV: Как рассчитать расстояние между камерой и объектом с помощью изображения?

Я новичок в OpenCV. Я использую следующую формулу для вычисления расстояния:

distance to object (mm) = focal length (mm) * real height of the object (mm) * image height (pixels)
                          ----------------------------------------------------------------
                                object height (pixels) * sensor height (mm)

Есть ли функция в OpenCV, которая может определять расстояние до объекта? Если нет, ссылка на образец кода?

4b9b3361

Ответ 1

Как рассчитать расстояние, заданное объектом известного размера

Вам нужно знать одну из двух вещей впереди

  • Фокусное расстояние (в мм и пикселях на мм)
  • Физический размер датчика изображения (для расчета пикселей на мм)

Я собираюсь использовать фокусное расстояние, так как не хочу, чтобы google отображал данные для датчика.

Откалибровать камеру

Используйте инструмент OpenCV calibrate.py и PNG шаблона Chessboard, предоставленный в исходном коде, для создания калибровочной матрицы. Я взял около 2 десятков фотографий шахматной доски с максимально возможной точки зрения и экспортировал файлы на свой Mac. Подробнее см. Документы калибровки камеры OpenCV.

Матрица калибровки камеры (камера заднего вида iPhone 5S)

RMS: 1.13707201375
camera matrix:
[[  2.80360356e+03   0.00000000e+00   1.63679133e+03]
 [  0.00000000e+00   2.80521893e+03   1.27078235e+03]
 [  0.00000000e+00   0.00000000e+00   1.00000000e+00]]
distortion coefficients:  [ 0.03716712  0.29130959  0.00289784 -0.00262589 -1.73944359]
  • f_x = 2803
  • f_y = 2805
  • c_x = 1637
  • c_y = 1271

Проверяя детали серии фотографий шахматной доски, вы нашли собственное разрешение (3264x2448) фотографий и в своих JPEG EXIF-заголовки, видимый в iPhoto, вы можете найти значение фокусного расстояния (4.15 мм). Эти элементы должны отличаться в зависимости от камеры.

Пиксели на миллиметр

Нам нужно знать пиксели на миллиметр (px/mm) на датчике изображения. На странице резекция камеры мы знаем, что f_x и f_y являются фокальными длинами, умноженными на масштабный коэффициент.

f_x = f * m_x
f_y = f * m_y

Так как для каждой формулы мы имеем две переменные, мы можем решить для m_x и m_y. Я просто усреднил 2803 и 2805, чтобы получить 2804.

m = 2804px / 4.15mm = 676px/mm 

Размер объекта в пикселях

Я использовал OpenCV (С++), чтобы извлечь Rotated Rect из точек и определил размер объекта как 41px. Заметьте, что я уже получил углы объекта, и я задаю ограничивающий прямоугольник для его размера.

cv::RotatedRect box = cv::minAreaRect(cv::Mat(points));

Маленькая морщина

Объект - 41px в видеоролике на фотоаппарате @640x480.

Преобразование px/mm в нижнем разрешении

3264/676 = 640/x
x = 133 px/mm

Таким образом, при 41px/133px/mm мы видим, что размер объекта на датчике изображения составляет 0,308 мм.

Формула расстояния

distance_mm = object_real_world_mm * focal-length_mm / object_image_sensor_mm
distance_mm = 70mm * 4.15mm / .308mm
distance_mm = 943mm

Это очень хорошо. Я измерил 910 мм и с некоторыми уточнениями, я могу, вероятно, уменьшить ошибку.

Обратная связь приветствуется.

Подобный подход треугольников

Adrian at pyimagesearch.com продемонстрировал другую технику с использованием аналогичных треугольников. Мы обсуждали эту тему заранее, и он взял подход с подобными треугольниками, и я сделал внутреннюю работу камеры.

Ответ 3

  • Чтобы получить сопоставление между реальным миром и камерой без какой-либо предварительной информации о камере, вам необходимо выполнить калибровку камеры... здесь вы можете найти какую-то теорию
  • Для расчета глубины, то есть расстояния между камерой и объектом, вам нужно как минимум два изображения одного и того же объекта, сделанных двумя разными камерами... которые в народе называют техникой стереовидения.