Добрый день уважаемые читатели ! Это вторая часть рассказа об использовании 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 и распечатаем. Для удобства я его наклеил на фанерную доску:
Давайте запустим программу калибровки:
rosrun camera_calibration cameracalibrator.py --size 8x6 --square 0.108 image:=/usb_cam/image_raw camera:=/usb_cam
Мы получим картинку:
Переместим немного шаблон и подождем пока шаблон не будет выделен в кадре (на шаблоне не появятся цветные линии с точками).
Переместим шаблон еще немного в сторону. Чтобы успешно выполнить калибровку нам нужно выполнить серию перемещений шаблона перед камерой из стороны в сторону так чтобы шаблон попал во все угловые позиции в поле зрения камеры (слева, справа, сверху и снизу). Справа от окна изображения с камеры в окне программы находится панель регистрации с тремя прогрессбарами:
- X фиксирует перемещение шаблона в направлении лево/право (горизонтальное) в поле зрения камеры
- Y фиксирует перемещение шаблона в направлении верх/низ (горизонтальное) в поле зрения камеры
- Size фиксирует приближение / удаление шаблона от камеры и наклон по отношению к камере.
- Skew фиксирует наклон шаблона влево, вправо, вверх и вниз (скос).
Таким образом для успешной калибровки важно чтобы шаблон оказался в разных углах кадра, занимал весь кадр а также был наклонен влево, вправо, вверх и вниз.
Калибровка fish eye камеры на Raspberry Pi может занять довольно много времени, поэтому запаситесь терпением. У меня процедура калибровки заняла 20 минут.
Когда калибровка будет завершена, кнопка Calibrate должна активироваться (подсветится цветом):
Также мы можем увидеть результаты калибровки в терминале:
Если вы удовлетворены результатом, нажмите кнопку 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
Откроется окно программы детекции:
Здесь мы увидим поток с камеры и результат детекции характерных признаков на объектах.
Для начала проведем тренировку детектора на наших объектах. Поместим первый объект перед камерой:
Нажмем правой кнопкой на левой панели Objects в окне и у нас откроется опция Add objects from scene. Выберем эту опцию и откроется окно добавления объекта:
Выбрав наилучшую позицию для объекта, нажмем кнопку Take Picture чтобы сделать снимок объекта:
Нам потребуется выделить объект на снимке. Используем курсор мышки для выделения объекта:
Нажмем на кнопку Next чтобы вырезать объект на снимке и перейдем к следующему шагу. После обрезки изображения мы получим полное число обнаруженных на объекте характерных признаков. Остается только нажать кнопку End чтобы добавить объект в базу обученных объектов детектора. Здесь мы видим последний шаг процедуры добавления объекта:
В итоге мы обучили детектор на одном объекте. Теперь можно попробовать детекцию объекта в сцене:
Сделаем вывод позиции обнаруженного объекта в терминал:
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 представляют 3x3 матрицу гомографии (используется для вычисления позиции и ориентации объекта, а также значения масштаба и сдвига).
Как показывают наблюдения, find_object_2d плохо справлется с детекцией объектов со слабой тектурой или без текстуры (textureless). Кроме того детектор неэффективен при детекции объекта под большим углом к объекту (если мы наблюдаем объект сбоку), или на большом расстоянии до объекта.
После завершения работы с детектором, find_object_2d нам предложит сохранить добавленные объекты на диск.
На этом пока все. Всем удачи и до новых встреч!
Автор: Владимир