Расстояние до объекта с помощью стереокамеры
есть ли способ рассчитать расстояние до конкретного объекта с помощью стереокамеры? Есть ли формула или что-то, чтобы получить расстояние, используя неравенство или угол?
3 ответов
Примечание: все, что описано здесь, можно найти в книге Learning OpenCV в главах о калибровке камеры и стереовидении. Вы должны прочитать эти главы, чтобы лучше понять следующие шаги.
один подход, который не требует, чтобы вы измеряли все встроенные и внешние камеры, - это использовать функции калибровки openCVs. Внутреннеприсущие части камеры (искажение объектива / skew etc) можно высчитать с cv:: calibrateCamera, пока extrinsics (отношение между левой и правой камерой) можно рассчитать с помощью CV::stereoCalibrate. Эти функции берут несколько точек в координатах пикселей и пытаются сопоставить их с координатами объектов реального мира. CV имеет аккуратный способ получить такие очки, распечатать черно-белую шахматную доску и использовать функции cv::findChessboardCorners/cv::cornerSubPix для их извлечения. Около 10-15 пар изображений шахматных досок должны делать.
матрицы вычисляется путем калибровки функции быть сохранены на диск, так что вам не придется повторять этот процесс каждый раз при запуске приложения. Здесь вы получаете несколько аккуратных матриц, которые позволяют создать карту исправления (cv::stereoRectify/cv::initUndistortRectifyMap), которая позже может быть применена к вашим изображениям с помощью CV::remap. Вы также получаете аккуратную матрицу под названием Q, которая является матрицей несоответствия глубине.
причина исправления изображений заключается в том, что после завершения процесса для пары изображений (при условии, что ваша калибровка правильно), каждый пиксель / объект в одном изображении можно найти на та же строка на другом изображении.
есть несколько способов вы можете идти отсюда, в зависимости от того, какие функции вы ищете в образе. Один из способов-использовать функции соответствия CVS stereo, такие как сопоставление Стереоблоков или сопоставление глобальных блоков. Это даст вам карту несоответствия для всего изображения, которое можно преобразовать в 3D-точки с помощью матрицы Q (cv:: reprojectImageTo3D).
падение этого заключается в том, что, если в изображении нет много информации о текстуре, CV не очень хорош в создании плотной карты несоответствия (вы получите пробелы в ней, где он не смог найти правильное несоответствие для данного пикселя), поэтому другой подход-найти точки, которые вы хотите сопоставить себе. Скажем, вы находите функцию / объект в x=40, y=110 в левом изображении и x=22 в правом изображении (поскольку изображения выпрямлены, они должны иметь то же самое y-значение). Диспаритет рассчитывается как d = 40-22 = 18.
построить cv:: Point3f(x,y,d), в нашем случае (40,110,18). Найдите другие интересные точки таким же образом, затем отправьте все точки в cv::perspectiveTransform (с матрицей Q в качестве матрицы преобразования, по существу, эта функция является cv::reprojectImageTo3D, но для разреженных карт диспаритета), и на выходе будут точки в системе координат XYZ с левой камерой в центре.
Я все еще работаю над этим, поэтому я не буду размещать весь код еще. Но я дам вам концептуальное решение.
вам понадобятся следующие данные в качестве входных данных (для обеих камер):
- положение камеры
- точка интереса камеры (точка, на которую смотрит камера)
- разрешение камеры (горизонтальное и вертикальное)
- угол обзора камеры (горизонтальный и вертикальный)
вы можете измерить последний сам, поместив камеру на листе бумаги и рисуя две линии и измеряя угол между этими линиями.
камеры не должны быть выровнены каким-либо образом, вам нужно только иметь возможность видеть ваш объект в обеих камерах.
теперь вычислите вектор от каждой камеры к вашему объекту. У вас есть (X,Y) пиксельные координаты объекта с каждой камеры, и вам нужно вычислить вектор (X,Y,Z). Обратите внимание, что в простом случае, когда объект виден прямо в в середине камеры, решение будет просто (камера.PointOfInterest-камера.Позиция.)
Как только у вас есть оба вектора, указывающие на вашу цель, линии, определенные этими векторами, должны пересекаться в одной точке в идеальном мире. В реальном мире они не были бы из-за небольших ошибок измерения и ограниченного разрешения камер. Поэтому используйте ссылку ниже, чтобы вычислить вектор расстояния между двумя линиями.
расстояние между двумя линиями
In эта ссылка: P0 - ваше первое положение камеры, Q0-ваше второе положение камеры, а U и v-векторы, начинающиеся с положения камеры и указывающие на вашу цель.
вас не интересует фактическое расстояние, они хотят вычислить. Вам нужен вектор Wc - мы можем предположить, что объект находится в середине Wc. Как только у вас есть положение вашего объекта в 3D-пространстве, вы также получаете любое расстояние, которое вам нравится.
Я скоро опубликую весь исходный код.
У меня есть исходный код для обнаружения человеческого лица и возвращает не только глубину, но и координаты реального мира с левой камерой (или правой камерой, я не мог вспомнить). Он адаптирован из исходного кода из "Learning OpenCV" и ссылается на некоторые веб-сайты, чтобы заставить его работать. Результат, как правило, довольно точен.