Добрый день уважаемые читатели Хабра. Несколько лет назад я писал об использовании камеры Raspberry Pi Camera Board на Raspberry Pi в связке с ROS. В этой и следующей статьях я бы хотел рассказать об использовании широкоугольной камеры типа fish eye на Raspberry Pi 3 с установленной Ubuntu 16.04. Кому интересно прошу под кат.
Для начала почему именно fish eye камера? Я видел много статей об использовании широкоугольных камер для визуальной одометрии и SLAM. Благодаря большему углу обзора fish eye камера повышает точность визуальной одометрии. Поэтому мне захотелось попробовать одну такую камеру с Raspberry Pi с поддержкой ROS. Я купил камеру с углом 160 градусов на dx.com за 28$. В комплект с камерой также входят две IR лампы для ночного видения:
В первой статье я расскажу об установке необходимых драйверов, OpenCV 3 и пакетов для поддержки камеры Raspberry Pi Camera Board в ROS.
Установка драйвера камеры fish eye на Raspberry Pi 3
Итак начнем. Подключимся к RPi 3 по SSH:
ssh -Y <user>@<ip>
Параметр -Y позволяет решить проблему с получением ошибки “Could not connect to display” при запуске некоторых GUI приложений (Qt, окно с изображением из программы OpenCV). Подробнее можно узнать здесь.
Для начала нам нужно включить поддержку драйвера камеры в настройках Raspberry Pi raspi-config. В Raspbian эта служба уже включена, в Ubuntu ее нужно установить:
sudo apt-get install raspi-config
Запустим raspi-config:
sudo raspi-config
Выберем опцию Interfacing, затем Pi Camera и нажмем Yes. И наконец Finish.
Проверим, что поддержка камеры включена с помощью утилиты raspistill:
raspistill -o mypicture.jpg
Если вы получили ошибку “Camera is not detected. Please check carefully the camera module is installed correctly” проверьте, правильно ли вы подключили камеру к Raspberry Pi. Также можно выполнить ребут системы (мне это помогло).
Попробуем записать видео:
raspivid -o myvideo.h264
Я получил изображение на мониторе, подключенном к Raspberry Pi. Мне не удалось получить всплывающее окно на моем компьютере при подключении по ssh.
Использование OpenCV 3 с fish eye камерой на Raspberry Pi
Установим библиотеку picamera[array]:
pip install "picamera[array]"
Установим необходимые зависимости для OpenCV. Для начала обновим пакетный менеджер apt и сделаем апгрейд предустановленных пакетов:
sudo apt-get update
sudo apt-get upgrade
Установим некоторые библиотеки:
sudo apt-get install build-essential cmake pkg-config
sudo apt-get install libjpeg8-dev libtiff5-dev libjasper-dev libpng12-dev
sudo apt-get install libavcodec-dev libavformat-dev libswscale-dev libv4l-dev
sudo apt-get install libxvidcore-dev libx264-dev
sudo apt-get install libgtk-3-dev
sudo apt-get install libatlas-base-dev gfortran
sudo apt-get install python2.7-dev python3.5-dev
Мы установим OpenCV 3 из исходников.
cd ~
wget -O opencv.zip https://github.com/Itseez/opencv/archive/3.1.0.zip
unzip opencv.zip
Нам также необходимо загрузить репозиторий opencv_contrib:
wget -O opencv_contrib.zip https://github.com/Itseez/opencv_contrib/archive/3.1.0.zip
unzip opencv_contrib.zip
Дело в том, что в OpenCV 3 пакеты с дескрипторами признаков (такие как SIFT и SURF) были перенесены в отдельный репозиторий contrib. Теперь для использования дескрипторов признаков нам необходимо отдельно скачивать репозиторий contrib.
Теперь мы наконец-то готовы к установке OpenCV. Мы можем выполнить cmake для компиляции OpenCV с нужными параметрами:
cd ~/opencv-3.1.0/
mkdir build
cd build
cmake -D CMAKE_BUILD_TYPE=RELEASE
-D CMAKE_INSTALL_PREFIX=/usr/local
-D INSTALL_PYTHON_EXAMPLES=ON
-D INSTALL_C_EXAMPLES=OFF
-D OPENCV_EXTRA_MODULES_PATH=~/opencv_contrib-3.1.0/modules
-D PYTHON_EXECUTABLE=~/.virtualenvs/cv/bin/python
-D BUILD_EXAMPLES=ON ..
Если cmake выполнился без ошибок, выполним make:
make -j4
При выполнении компиляции я получил ошибку “Segmentation fault”. Если вы получили такую же ошибку, выполните make clean для удаления результатов компиляции и выполните make с одним ядром:
make clean
make
У меня процедура компиляции заняла 3 часа. Наконец выполним установку OpenCV 3:
sudo make install
sudo ldconfig
Здесь есть интересный нюанс, связанный с ROS Kinetic. Если вы устанавливаете ROS Kinetic, то ROS добавляет путь к библиотекам Python (/opt/ros/kinetic/lib/python2.7/dist-packages) в системный путь при выполнении команды source /opt/ros/kinetic/setup.bash. Это ведет к некоторым проблемам при последующей установке OpenCV из исходников (подробнее об этом написано здесь). Чтобы решить проблему, нужно удалить строку ‘source /opt/ros/kinetic/setup.bash’ из файла .bashrc. Не забудем выполнить:
source ~/.bashrc
Давайте проверим, что OpenCV теперь корректно линкуется из Python.
Создадим папку для проекта и простой тестовый скрипт:
mkdir PiCamera && cd PiCamera
vim test_cam.py
Добавим следующий код в файл:
from picamera.array import PiRGBArray
from picamera import PiCamera
import time
import cv2
# initialize the camera and reference the raw camera capture
camera = PiCamera()
rawCapture = PiRGBArray(camera)
# allow camera to warmup
time.sleep(0.1)
# grab an image
camera.capture(rawCapture, format="bgr")
image = rawCapture.array
cv2.imshow("Capture", image)
cv2.waitKey(0)
Запустим скрипт:
python test_cam.py
В случае успеха мы получим примерно такую картинку:
Давайте теперь попробуем записать видео с камеры.
vim test_videom.py
Добавьте в файл вот такой код:
# import the necessary packages
from picamera.array import PiRGBArray
from picamera import PiCamera
import time
import cv2
# initialize the camera and grab a reference to the raw camera capture
camera = PiCamera()
camera.resolution = (640, 480)
camera.framerate = 32
rawCapture = PiRGBArray(camera, size=(640, 480))
# allow the camera to warmup
time.sleep(0.1)
# capture frames from the camera
for frame in camera.capture_continuous(rawCapture, format="bgr", use_video_port=True):
# grab the raw NumPy array representing the image, then initialize the timestamp
# and occupied/unoccupied text
image = frame.array
# show the frame
cv2.imshow("Frame", image)
key = cv2.waitKey(1) & 0xFF
# clear the stream in preparation for the next frame
rawCapture.truncate(0)
# if the `q` key was pressed, break from the loop
if key == ord("q"):
break
Давайте попробуем что-нибудь поинтереснее, например, добавим детекцию краев. Я здесь использую детектор Кенни (код взят отсюда):
from picamera.array import PiRGBArray
from picamera import PiCamera
import time
import cv2
import numpy as np
# initialize the camera and grab a reference to the raw camera capture
camera = PiCamera()
camera.resolution = (640, 480)
camera.framerate = 32
rawCapture = PiRGBArray(camera, size=(640, 480))
# allow the camera to warmup
time.sleep(0.1)
# capture frames from the camera
for frame in camera.capture_continuous(rawCapture, format="bgr", use_video_port=True):
# grab the raw NumPy array representing the image, then initialize the timestamp
# and occupied/unoccupied text
image = frame.array
hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
lower_red = np.array([30,150,50])
upper_red = np.array([255,255,180])
mask = cv2.inRange(hsv, lower_red, upper_red)
res = cv2.bitwise_and(image,image, mask= mask)
edges = cv2.Canny(res,100,200)
# show the frame
cv2.imshow("Frame", image)
cv2.imshow("Edges", edges)
key = cv2.waitKey(1) & 0xFF
# clear the stream in preparation for the next frame
rawCapture.truncate(0)
# if the `q` key was pressed, break from the loop
if key == ord("q"):
break
Вот результат запуска программы:
Добавление поддержки камеры Raspberry Pi Camera в ROS
Теперь добавим возможность работать с fish eye камерой для Raspberry Pi из ROS. Для начала установим необходимый драйвер V4L2 для Raspberry Pi камеры (можно подробнее прочитать здесь). Выполним команду:
sudo rpi-update
и сделаем ребут системы. Теперь добавим драйвер:
sudo modprobe bcm2835-v4l2
Проверим, что устройство /dev/video0 доступно:
ll /dev/video0
Вывод будет таким:
crw-rw----+ 1 root video 81, 0 Mar 17 15:47 /dev/video0
Скачаем пакет usb_cam:
sudo apt-get install ros-kinetic-usb-cam
source /opt/ros/kinetic/setup.bash
Запустим ROS мастер и rqt_image_view:
roscore
roslaunch usb_cam usb_cam-test.launch
rosrun rqt_image_view rqt_image_view
Выберем топик /usb_cam/image_raw. Мы получим такую картинку:
Теперь fish eye камеру можно использовать с любыми пакетами компьютерного зрения в ROS. В следующий раз мы попробуем детекцию объектов. Всем удачи в экспериментах и до новых встреч!
Автор: Владимир