ЭБАС
  • Подготовка к чемпионатам WSR по компетенции ЭБАС
  • 3D моделирование
    • Моделирование узла квадрокоптера
    • Слайсинг
    • Самостоятельная работа
  • Автономный полет
    • Быстрая настройка для ручного пилотирования
    • Быстрая настройка для автономного полета
    • Конкурсное задание
    • Программирование на языке Python
      • Логические выражения и операторы
      • Ввод и вывод данных
      • Типы данных. Переменные
      • Ветвление. Условный оператор
      • Ошибки и исключения. Обработка исключений
      • Множественное ветвление: if-elif-else
      • Циклы в программировании. Цикл while
      • Функции в программировании
      • Локальные и глобальные переменные
      • Возврат значений из функции. Оператор return
      • Параметры и аргументы функции
      • Встроенные функции
      • Модули
      • Генератор псевдослучайных чисел – random
      • Списки
      • Цикл for
      • Функция enumerate
      • Строки
      • Кортежи
      • Словари
      • Файлы
    • Программирование полета в Gazebo
    • Программирование полета в реальном мире
      • Установка и подключение Raspberry Pi на квадрокоптере
      • Подключение по wi-fi
      • Просмотр топиков
      • Linux-команды
      • Настройки внутренних файлов образа ОС
      • Подключение wi-fi и настройка в QGroundControl
      • Создание Aruco карты
      • Создание автономной программы программы
      • Полет по квадрату
    • Распознавание цветов
      • Распознавание цвета с захватом одного кадра
    • Распознавание QR-кодов
      • Распознавание QR-кода через подписку на топик
        • Функции рисования компьютерного зрения
      • Распознавание QR-кода с захватом одного кадра
        • Полет по точкам, используя координаты из QR-кода
  • Диагностика и ремонт БПЛА
    • Диагностика
  • Мониторинг
    • Заполнение разрешительной документации
    • Автономная программа для мониторинга
  • ЭКСПЛУАТАЦИЯ ПОЛЕЗНОЙ НАГРУЗКИ
    • Установка захвата и подключение
  • Внешнее пилотирование
    • Симулятор Geoscan Trainer
  • ЛЕТАЮЩАЯ РОБОТОТЕХНИКА
    • Настройка сервера
    • Настройка клиента
Powered by GitBook
On this page

Was this helpful?

  1. Автономный полет
  2. Распознавание цветов

Распознавание цвета с захватом одного кадра

PreviousРаспознавание цветовNextРаспознавание QR-кодов

Last updated 3 years ago

Was this helpful?

Напишем программу по распознаванию цветных объектов. Сразу скажу, что эта область обширна, и здесь мы будем касаться лишь той небольшой части, которая нам нужна для соревнований WorldSkills.

Для начала откроем гитбук разработчика квадрокоптера Клевер и скопируем готовый скрипт, который будем перерабатывать:

Скопируем этот код в пустой текстовый файл с расширением .py. На забудем изменить наименование импортирования модуля clover.

Отлично, теперь удалим все лишнее, и оставим только фрагмент по распознаванию цветов:

Итого, наш код принимает следующий вид:

Прокомментируем теперь каждую строчку:

#импорт необходимых модулей и библиотек
import rospy
import cv2 as cv
from clover import srv
from std_srvs.srv import Trigger
from cv_bridge import CvBridge
from sensor_msgs.msg import Image
from clover.srv import SetLEDEffect


#инициализация ноды (программы)
rospy.init_node('flight')

#инициализация используемых сервисов 
bridge = CvBridge()
set_effect = rospy.ServiceProxy('led/set_effect', SetLEDEffect)
get_telemetry = rospy.ServiceProxy('get_telemetry', srv.GetTelemetry)
navigate = rospy.ServiceProxy('navigate', srv.Navigate)
navigate_global = rospy.ServiceProxy('navigate_global', srv.NavigateGlobal)
set_position = rospy.ServiceProxy('set_position', srv.SetPosition)
set_velocity = rospy.ServiceProxy('set_velocity', srv.SetVelocity)
set_attitude = rospy.ServiceProxy('set_attitude', srv.SetAttitude)
set_rates = rospy.ServiceProxy('set_rates', srv.SetRates)
land = rospy.ServiceProxy('land', Trigger)

#создание топика для просмотра распознанного изображения
color_debug = rospy.Publisher("/color_debug", Image)


#объявление процедуры check_temp, при вызове которой будет распознавание цветов
def check_temp(data):
    #создание переменной frame, где будет храниться изображение с камеры. Изображение это постоянно обрабатывается. В квадратных скобках определена рамка, откуда берется изображение. Кодировка изображения brg8 (8-ми битное изображение с кодировкой BGR)
    frame = bridge.imgmsg_to_cv2(data, 'bgr8')[80:160, 100:220]  
   
   #задание для каждого цвета диапазона в кодировке BGR. В результате в каждую из переменных запишется бинарное представление цвета (0 - если цвет не попадет в диапазон и 255 - если попадает). Это бинарное представление представлено в виде матрицы.
    red = cv.inRange(frame, (165, 70, 158), (255, 209, 255))
    yellow = cv.inRange(frame, (10, 80, 88), (49, 220, 225))
    green = cv.inRange(frame, (26, 28, 60), (135, 162, 225))

    #зададим словарь color, где запишем для каждого ключа 'r', 'y', 'g' значения из бинарной матрицы только не нулевые значения
    color = {'r': cv.countNonZero(red),
             'y': cv.countNonZero(yellow),
             'g': cv.countNonZero(green)}
    
    #публикация топика для просмотра распознанного изображения
    color_debug.publish(bridge.cv2_to_imgmsg(frame, 'bgr8')) 
   
    #зададим условие, если максимальное значение из словаря равно ключу 'y', тогда выводим на экран сообщение sbrosheno. Простыми словами, если он увидел желтый цвет, тогда выводить сообщение sbrosheno
    if max(color, key=color.get) == 'y':
        print('sbrosheno') 

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

В итоге наш код примет следующий вид:

Теперь добавим полет в цветовую метку с координатами (x=2, y=0) и не забудем вызвать процедуру для распознавания цветовой метки. Будем распознавать красный цвет, поэтому будет в условии сравнивать с ключом 'r':

Сохраним полученный код и запустим квадрокоптер.

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

Сохраним и запустим код:

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

Итого:

для первого числа максимальное — 134, минимальное -113

для второго числа максимальное — 150, минимальное -134

для третьего числа максимальное — 163, минимальное -151

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

Получим диапазон:

максимальное значение (174, 194, 203)

минимальное значение (75, 94, 111)

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

Теперь вновь запустим нашу программу.

Как видите, теперь все работает и красный цвет он определяет. Однако, вы должны знать, что на распознавание цвета влияют многие факторы, один из которых это освещение в помещении. В симуляторе Gazebo идеальные условия, и здесь освещение постоянное, поэтому настройка диапазона проводится за один проход. В реальности, таких проходов для получения выборки диапазона, возможно более 2-ух раз.

Для более точного определения поменяем границы определения на следующие:

frame = bridge.imgmsg_to_cv2(rospy.wait_for_message('main_camera/image_raw', Image), 'bgr8')[100:140, 130:170]  

ЗАДАНИЯ НА САМОСТОЯТЕЛЬНУЮ РАБОТУ:‌

  1. Распознайте цветовые метки в других двух точках и выведите сообщение о результате. Если вы цвет распознали выведите сообщение «Raspoznal», в противном случае «Neraspoznal». Координаты первой цветовой метки (x=2, y=0). Координаты второй цветовой метки (x=1, y=2). Координаты третьей цветовой метки (x=3, y=3).

https://clover.coex.tech/ru/