Урок 12

Введение: Данный урок, является первым из группы уроков на использование компьютерного зрения для анализа данных видеопотока нашего робота. Мы слегка коснулись компьютерного зрения в предыдущем уроке, когда получали и анализировали данные тепловизора, а теперь поговорим обо всем этом подробнее. Тема компьютерного зрения очень обширна и мы ни в коем случае не претендуем на исчерпывающий обзор по ней. Данный урок стоит рассматривать как точку входа в тему компьютерного зрения и его использования с реальными роботами. Мы рассмотрим базовые принципы применяемые при работе с изображениями камеры, а так же реализацию интеграции данных полученных при обработке изображения и алгоритмов управления роботом. Эти концепции мы будем изучать на примере получения изображения желтого шарика и определения координат его центра для дальнейшего использования в задаче управления роботом.

Подготовка: Данную задачу можно решать в любой комбинации полигона, подойдет и "Офис" и "Дорога". В данном уроке мы не будем передвигать робота, таким образом, нам не нужна какая-то специальная подготовка пространства вокруг.

Для реализации всех типов задач связанных с компьютерным зрением в рамках наших методических материалов, необходимо убедиться, что видео-поток с камеры перенаправлен в ROS (По умолчанию он направлен в web-интерфейс). В связи с тем, что два потока не могут работать с камерой одновременно, учащимся необходимо переконфигурировать файл запуска /etc/ros/turtlebro.d/turtlebro.launch таким образом, чтобы по умолчанию видео-поток шел в ROS:

<arg name="run_turtlebro_web" default="false"/>
<arg name="run_ros_camera" default="true"/>

Обратите внимание, что после перенаправления видео-потока, изображение с фронтальной камеры робота будет недоступно через веб-интерфейс. При необходимости перемещения робота по полигону, видео контроль осуществляйте по камере установленной на полигоне или попросите учащихся переключить видео-поток обратно, заменив значения переменных в файле /etc/ros/turtlebro.d/turtlebro.launch, на следующие:

<arg name="run_turtlebro_web" default="true"/>
<arg name="run_ros_camera" default="false"/>

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

Решение Метрической задачи отвечает на вопрос, какого размера объекты изображенные на картинке.

Обе эти задачи требуют определенных шагов при их решении. В частности:

  1. Необходимо получить и дискретезировать изображение, т.е. получить его в цифровом виде, который может быть подвергнут дальнейшему анализу и обработке. В общем случае надо перевести изображение в массив точек соответствующих цветов, при этом размер массива может совпадать с разрешением камеры.
  2. Далее надо провести предобработку изображения, к примеру, уменьшить разрешение, или изменить цветовую модель, или отфильтровать интересующие нас цвета, или изменить яркость, или подавить шумы, увеличить резкость или наоборот размыть изображение, в общем сделать так, чтобы набор признаков на изображении, по которым алгоритм будет решать семантическую и метрическую задачу был бы наиболее ярко выраженным.
  3. Далее к полученному обработанному изображению мы применяем семантические и метрические алгоритмы. Причем каждый из них может быть как независим друг от друга, так может быть и зависим.
  4. Результатом работы алгоритмов являются ответы на вопросы что именно и каких размеров находится на изображении. При этом в большинстве случаев алгоритмы дают вероятностный результат. Т.е. размеры на изображении даются с некой погрешностью, как и классификация объектов.

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

Задача: Получить изображение с камеры робота и сохранить его в файл.

Общий алгоритм решения:

  1. Подписаться на топик камеры
  2. Получить массив данных с камеры
  3. Декодировать данный массив в формат jpg
  4. Записать декодированный массив в jpg файл

Решение: Для начала импортируем все библиотеки и структуры данных, которые нам понадобятся. Это rospy, и numpy и OpenCV. Rospy мы будем как и ранее использовать для реализации взаимодействия с ROS, numpy для обработки массивов изображения и OpenCV для декодирования массива и записи его в файл. Кроме того нам понадобится структура данных CompressedImage, которая и содержит данные камеры.

import rospy
import cv2
import numpy as np
from sensor_msgs.msg import CompressedImage

Далее инициализируем ноду и опишем функцию обратного вызова для подписчика на данные камеры, которого создадим далее.

rospy.init_node("photographer")

def cb_video_capture(image_msg):
        global image_from_ros_camera
        np_arr = np.frombuffer(image_msg.data, np.uint8)
        image_from_ros_camera = cv2.imdecode(np_arr, cv2.IMREAD_COLOR)

Данная функция будет принимать структуру CompressedImage от подписчика, переводить ее в формат массива чисел вида int8 и далее превращать этот массив в JPG при помощи функции imdecode библиотеки OpenCV. В принципе мы могли бы самостоятельно превращать массив данных камеры в JPG, для этого к исходному массиву нам надо было бы добавить стандартный заголовок и стандартное окончание файла JPG. Но в данном случае эту простую манипуляцию мы выполним при помощи встроенной функции cv2.imdecode.

Обратите внимание, что мы сделали переменную image_from_ros_camerа - глобальной. Это связано с тем, что превращать ее в файл мы будем вне нашей функции обратного вызова и нам надо будет иметь к ней доступ из другой части программы.

Далее объявим подписчика на данные камеры и сделаем паузу в 1 секунду, чтобы подписчик успел создаться, данные с камеры успели поступить и все функции превращения массивов отработали.

rospy.Subscriber("/front_camera/compressed", CompressedImage, cb_video_capture)
rospy.sleep(1)

Далее нам надо взять готовые данные из глобальной переменной image_from_ros_camera и записать их в файл при помощи функции imwrite библиотеки OpenCV. Назовем наш файл "ball_JPG.jpg", т.к. в дальнейшем мы будем использовать этот код для поиска шарика.

cv2.imwrite("/home/pi/ball_JPG.jpg", image_from_ros_camera)

Проверка решения:

Попросите учащихся сохраним программу на роботе и запустить.

После того, как программа отработала, в домашней директории робота должен появиться файл ball_JPG.jpg с изображением с камеры. Попросите учащихся открыть его в режиме демонстрации экрана в Discord.

В следующих уроках, мы с вами произведем предобработку изображения с камеры, передадим ее в функцию обрабатывающую изображение по алгоритму визуальных моментов, найдем желтый шарик на изображении и определим его центр в координатах изображения.

results matching ""

    No results matching ""