Использование камеры Fish eye на Raspberry Pi 3 с ROS — часть 2

Добрый день уважаемые читатели Хабра! Это вторая часть рассказа об использовании fish eye камеры на Raspberry Pi 3. Первую часть можно найти здесь. В этой статье я расскажу о калибровке fish eye камеры и применении камеры в детекции объектов с помощью пакета find_object_2d. Кому интересно, прошу под кат.

Калибровка камеры fish eye с использованием camera_calibration


Здесь я описываю процедуру калибровки на основе официального мануала на портале ros.org.
Для выполнения калибровки нам нужен пакет camera-calibration. Мы можем его установить с помощью apt:

sudo apt-get install ros-kinetic-camera-calibration

Нам нужен будет шаблон checkerboard. Скачаем шаблон с официального мануала на ros.org и распечатаем. Для удобства я его наклеил на фанерную доску:

image

Давайте запустим программу калибровки:

rosrun camera_calibration cameracalibrator.py --size 8x6 --square 0.108 image:=/usb_cam/image_raw camera:=/usb_cam


Мы получим картинку:

image

Переместим немного шаблон и подождем пока шаблон не будет выделен в кадре (на шаблоне не появятся цветные линии с точками).

image

image

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

  • X фиксирует перемещение шаблона в направлении лево/право (горизонтальное) в поле зрения камеры
  • Y фиксирует перемещение шаблона в направлении верх/низ (горизонтальное) в поле зрения камеры
  • Size фиксирует приближение / удаление шаблона от камеры и наклон по отношению к камере.
  • Skew фиксирует наклон шаблона влево, вправо, вверх и вниз (скос).

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

Калибровка fish eye камеры на Raspberry Pi может занять довольно много времени, поэтому запаситесь терпением. У меня процедура калибровки заняла 20 минут.

Когда калибровка будет завершена, кнопка Calibrate должна активироваться (подсветится цветом):

image

Также мы можем увидеть результаты калибровки в терминале:

image

Если вы удовлетворены результатом, нажмите кнопку COMMIT. Окно программы закроется и вы увидите в терминале сообщение «writing calibration data to …».

Проверим, что был создан указанный файл:

ll ~/.ros/camera_info/head_camera.yaml
-rw-rw-r-- 1 vladimir vladimir 592 Apr 14 14:02 /home/vladimir/.ros/camera_info/head_camera.yaml

Калибровка завершена. Теперь полученные данные калибровки можно использовать в алгоритмах визуальной локализации и SLAM в ROS.

Детекция объектов с помощью find_object_2d


Установить пакет достаточно просто. Устанавливаем его из репозитория apt в Ubuntu 16.04 для ROS Kinetic:

sudo apt-get install ros-kinetic-find-object-2d
source /opt/ros/kinetic/setup.bash

Запустим ROS master и rqt_image_view:

roscore
roslaunch usb_cam usb_cam-test.launch


С помощью следующей команды запустим узел детектора:

rosrun find_object_2d find_object_2d image:=/usb_cam/image_raw

Откроется окно программы детекции:

image

Здесь мы увидим поток с камеры и результат детекции характерных признаков на объектах.
Для начала проведем тренировку детектора на наших объектах. Поместим первый объект перед камерой:

image

Нажмем правой кнопкой на левой панели Objects в окне и у нас откроется опция Add objects from scene. Выберем эту опцию и откроется окно добавления объекта:

image

Выбрав наилучшую позицию для объекта, нажмем кнопку Take Picture чтобы сделать снимок объекта:

image

Нам потребуется выделить объект на снимке. Используем курсор мышки для выделения объекта:

image

Нажмем на кнопку Next чтобы вырезать объект на снимке и перейдем к следующему шагу. После обрезки изображения мы получим полное число обнаруженных на объекте характерных признаков. Остается только нажать кнопку End чтобы добавить объект в базу обученных объектов детектора. Здесь мы видим последний шаг процедуры добавления объекта:

image

В итоге мы обучили детектор на одном объекте. Теперь можно попробовать детекцию объекта в сцене:

image

Сделаем вывод позиции обнаруженного объекта в терминал:

rosrun find_object_2d print_objects_detected

Вывод будет таким:

Object 1 detected, Qt corners at (259.387238,103.530960) (448.684052,79.495495) (282.419050,240.049667) (458.438938,199.656717)
---
Object 1 detected, Qt corners at (255.340408,104.615120) (451.348079,75.302353) (284.672425,230.382223) (452.696585,197.625600)
---
Object 1 detected, Qt corners at (253.440521,102.973320) (447.226440,76.793541) (278.530854,238.918013) (454.377219,197.526599)
---


Выведем список топиков:

rostopic list

В списке появилось два новых топика: /objects и /objectsStamped.

Выведем информацию об обнаруженных объектах:

rostopic echo /objects

layout: 
  dim: []
  data_offset: 0
data: [1.0, 266.0, 177.0, 0.7527905702590942, 0.060980819165706635, 0.00022385441116057336, 0.3012462854385376, 0.8929792046546936, 0.0008534671505913138, 334.9065856933594, 182.55294799804688, 1.0]
---


Здесь второе и третье значения (266.0, 177.0) представляют ширину и высоту объекта. Все остальные значения в поле data представляют 3×3 матрицу гомографии (используется для вычисления позиции и ориентации объекта, а также значения масштаба и сдвига).

Как показывают наблюдения, find_object_2d плохо справлется с детекцией объектов со слабой тектурой или без текстуры (textureless). Кроме того детектор неэффективен при детекции объекта под большим углом к объекту (если мы наблюдаем объект сбоку), или на большом расстоянии до объекта.

image

После завершения работы с детектором, find_object_2d нам предложит сохранить добавленные объекты на диск.
На этом пока все. Всем удачи и до новых встреч!

© Habrahabr.ru