Машинное зрение на Raspberry Pi AI Camera и YOLOv8

Практический курс по созданию системы компьютерного зрения полного цикла: от подготовки данных для сегментации до запуска нейросети на чипе Sony IMX500.

1. Настройка окружения: Raspberry Pi 4 и подключение модуля AI Camera

Введение в курс: Машинное зрение на граничных устройствах

Добро пожаловать на курс «Машинное зрение на Raspberry Pi AI Camera и YOLOv8». Мы начинаем увлекательное путешествие в мир Edge AI — искусственного интеллекта, работающего непосредственно на устройстве, без необходимости отправлять данные в облако. Это критически важно для задач, требующих мгновенной реакции, конфиденциальности и работы при нестабильном интернете.

В этом курсе мы пройдем путь от «железа» до создания собственной системы детекции и сегментации объектов. Наша главная цель — научиться использовать возможности сенсора Sony IMX500, который лежит в основе Raspberry Pi AI Camera. Этот сенсор уникален тем, что имеет встроенный нейропроцессор (NPU), позволяющий обрабатывать изображения еще до того, как они попадут в оперативную память вашего Raspberry Pi.

В этой первой статье мы сосредоточимся на фундаменте: правильной сборке аппаратной части и настройке программного окружения.

Аппаратное обеспечение: Что нам понадобится

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

1. Raspberry Pi 4 Model B

Это «мозг» нашей системы. Хотя Raspberry Pi 5 уже существует, «четверка» остается золотым стандартом для многих индустриальных проектов благодаря своей стабильности, широкой поддержке сообщества и достаточному количеству линий CSI (Camera Serial Interface) для подключения камер.

Рекомендуемые характеристики: * ОЗУ: Минимум 4 ГБ (желательно 8 ГБ для комфортной компиляции и обучения моделей, если вы решите делать это на самом устройстве). * Охлаждение: Обязательно используйте активное охлаждение (вентилятор) или массивный радиатор. Обработка видеопотока и работа с нейросетями существенно нагревают процессор.

2. Raspberry Pi AI Camera

Главный герой нашего курса. Это не просто камера, это интеллектуальный сенсор.

Ключевые особенности: * Сенсор: Sony IMX500. * Разрешение: 12.3 мегапикселя. * Встроенный ускоритель: CNN-акселератор, способный выполнять инференс (вывод) нейросетей прямо на матрице.

!Комплект оборудования: одноплатный компьютер и модуль ИИ-камеры

3. Периферия

* Карта памяти: MicroSD объемом от 32 ГБ (класс A1 или A2 для быстрой работы с файлами). * Блок питания: Официальный USB-C блок питания (5.1V, 3A). Качественное питание критически важно для стабильной работы NPU камеры. * Шлейф: Стандартный 15-pin на 22-pin (если используется RPi Zero) или стандартный 15-pin на 15-pin для RPi 4. Обычно идет в комплекте с камерой.

Подключение камеры к Raspberry Pi

Процесс подключения требует аккуратности. Интерфейс CSI (Camera Serial Interface) обеспечивает высокую пропускную способность, необходимую для передачи видеоданных.

  • Отключите питание. Никогда не подключайте и не отключайте шлейфы при включенном устройстве. Это может сжечь порт или камеру.
  • Найдите порт CAMERA. На Raspberry Pi 4 он находится между портами HDMI и аудиоразъемом.
  • Поднимите фиксатор. Аккуратно потяните вверх пластиковую планку на разъеме.
  • Вставьте шлейф. Контакты шлейфа (серебристая сторона) должны быть направлены в сторону, противоположную фиксатору (обычно в сторону разъема HDMI). Синяя полоска на шлейфе должна смотреть на фиксатор.
  • Защелкните фиксатор. Нажмите на планку вниз до щелчка.
  • !Схема подключения шлейфа камеры к порту CSI

    Установка операционной системы

    Для работы с AI Camera настоятельно рекомендуется использовать последнюю версию Raspberry Pi OS (Bookworm). Старые версии (Bullseye или Buster) могут не иметь необходимых драйверов ядра для IMX500.

    Шаги установки:

  • Скачайте и установите Raspberry Pi Imager на ваш основной компьютер.
  • Вставьте SD-карту в кардридер.
  • В Imager выберите устройство: Raspberry Pi 4.
  • Выберите ОС: Raspberry Pi OS (64-bit). 64-битная версия обязательна для эффективной работы современных библиотек машинного обучения, таких как PyTorch и TensorFlow Lite.
  • Настройте предварительные параметры (нажав шестеренку): имя хоста, SSH, Wi-Fi.
  • Нажмите WRITE и дождитесь окончания записи.
  • После загрузки Raspberry Pi выполните обновление системы:

    Настройка программного окружения

    В современных версиях Raspberry Pi OS (начиная с Bookworm) политика управления пакетами Python изменилась (PEP 668). Теперь нельзя просто так устанавливать пакеты через pip в системное окружение. Мы будем использовать виртуальные окружения.

    1. Создание виртуального окружения

    Создадим папку для проекта и виртуальное окружение:

    Активируем окружение (эту команду нужно вводить каждый раз при открытии нового терминала для работы с проектом):

    2. Установка библиотек для работы с камерой

    Raspberry Pi AI Camera работает на базе стека libcamera и rpicam-apps. Убедимся, что необходимые утилиты установлены:

    3. Установка YOLOv8

    Мы будем использовать библиотеку ultralytics, которая предоставляет удобный интерфейс для работы с моделями YOLO (You Only Look Once). Это state-of-the-art алгоритм для детекции объектов в реальном времени.

    В активированном виртуальном окружении выполните:

    Также установим PyTorch (обычно подтягивается автоматически, но лучше проверить):

    Немного теории: Почему важен интерфейс CSI?

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

    Формула расчета битрейта () для несжатого видео:

    Где: * — битрейт (бит в секунду). * — ширина кадра в пикселях (например, 1920). * — высота кадра в пикселях (например, 1080). * — глубина цвета (бит на пиксель). Для стандартного RGB это 24 бита (8 бит 3 канала). * — частота кадров (FPS, например, 30).

    Подставим значения для Full HD потока:

    Где: * — количество пикселей в одном кадре. * — количество бит информации на один пиксель. * — количество кадров в секунду. * — итоговая скорость потока данных.

    USB 2.0 имеет предел 480 Мбит/с, что явно недостаточно для несжатого видео. USB 3.0 справляется, но создает большую нагрузку на CPU для обработки прерываний. Интерфейс CSI подключен напрямую к GPU/ISP процессора Broadcom на Raspberry Pi, что позволяет обрабатывать этот поток с минимальными задержками и почти нулевой нагрузкой на центральный процессор.

    Проверка работоспособности

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

  • Проверьте подключение на уровне системы:
  • Вы должны увидеть в выводе упоминание imx500.

  • Запустите тестовый просмотр (если у вас подключен монитор или вы используете X11 forwarding):
  • Эта команда включит камеру на 5 секунд.

  • Проверим работу YOLOv8 на процессоре (пока без использования NPU камеры, просто чтобы убедиться, что софт работает).
  • Создайте файл test_yolo.py:

    Запустите скрипт:

    Если в папке появился файл result.jpg с обведенным автобусом — поздравляю! Ваше окружение настроено и готово к работе.

    Заключение

    Сегодня мы подготовили надежный плацдарм для дальнейшей работы. Мы собрали аппаратную часть, установили современную ОС и настроили Python-окружение. Мы также убедились, что библиотека YOLOv8 функционирует.

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

    2. Подготовка данных: сбор изображений и разметка сегментированных объектов для YOLOv8

    Подготовка данных: сбор изображений и разметка сегментированных объектов для YOLOv8

    В предыдущей статье мы успешно настроили Raspberry Pi 4 и подключили модуль AI Camera. Теперь, когда аппаратная часть готова, мы переходим к самому важному этапу любого проекта в области машинного обучения — работе с данными.

    В мире искусственного интеллекта существует поговорка: «Garbage In, Garbage Out» (Мусор на входе — мусор на выходе). Какую бы мощную архитектуру нейросети вы ни использовали, если данные для обучения некачественные или плохо размеченные, результат будет неудовлетворительным. В этой статье мы научимся собирать собственный датасет и размечать его для задачи сегментации.

    Детекция против Сегментации: в чем разница?

    Прежде чем начать, важно понять, какую задачу мы решаем. YOLOv8 поддерживает несколько режимов работы, но нас интересуют два основных:

  • Детекция объектов (Object Detection): Модель находит объект и выделяет его прямоугольной рамкой (Bounding Box). Это быстро, но грубо. Мы знаем, где примерно находится объект, но не знаем его точных границ.
  • Сегментация экземпляров (Instance Segmentation): Модель находит объект и выделяет его точный контур (маску). Это позволяет отделить объект от фона с точностью до пикселя.
  • !Визуальное различие между прямоугольной детекцией и точной сегментацией объекта.

    Для нашего курса мы выбираем сегментацию, так как возможности Raspberry Pi AI Camera и сенсора IMX500 позволяют выполнять эту сложную задачу аппаратно.

    Этап 1: Сбор изображений

    Лучший датасет — это тот, который собран в условиях, максимально приближенных к боевым. Поэтому мы будем использовать саму Raspberry Pi AI Camera для съемки объектов.

    Почему нельзя просто скачать картинки из интернета?

    Каждая камера имеет свои оптические искажения, цветопередачу и уровень шума. Если вы обучите модель на идеальных стоковых фото, а потом запустите её на реальной камере в полутемном цеху, точность упадет. Обучение на данных с целевого устройства (Target Device) всегда дает лучший результат.

    Скрипт для сбора данных

    Мы напишем простой Python-скрипт, который позволит нам видеть видеопоток и сохранять кадры нажатием клавиши.

    Убедитесь, что вы находитесь в виртуальном окружении (source venv/bin/activate), и установите OpenCV, если он еще не установлен:

    Создайте файл capture_data.py:

    Советы по съемке:

  • Разнообразие ракурсов: Снимайте объект сверху, сбоку, под углом.
  • Разнообразие фона: Если вы хотите детектировать кружку, снимите её на столе, на полу, на подоконнике.
  • Освещение: Сделайте кадры при ярком свете и в полумраке.
  • Перекрытия: Частично закройте объект рукой или другим предметом — нейросеть должна учиться узнавать объект даже по его части.
  • Наберите минимум 50–100 изображений для начала.

    Этап 2: Разметка данных (Аннотация)

    Теперь, когда у нас есть папка с фотографиями, нужно объяснить компьютеру, что на них изображено. Этот процесс называется аннотацией.

    Для сегментации нам нужно не просто выделить объект рамкой, а обвести его контур точками (полигоном).

    Инструменты для разметки

    Существует множество инструментов. Самые популярные: * CVAT (Computer Vision Annotation Tool): Мощный профессиональный инструмент (web-based). * LabelMe: Простая программа на Python, запускается локально. * Roboflow: Удобная онлайн-платформа, которая также помогает с управлением версиями датасета.

    Для новичков мы рекомендуем Roboflow или LabelMe, так как они интуитивно понятны. В рамках статьи рассмотрим общий принцип, применимый везде.

    Процесс разметки полигонами

  • Загрузите изображения в инструмент.
  • Выберите инструмент «Polygon» (Полигон).
  • Аккуратно проставьте точки по периметру объекта. Чем больше точек на изгибах, тем точнее маска.
  • Присвойте класс объекту (например, raspberry_pi).
  • Сохраните разметку.
  • !Процесс создания полигональной маски для сегментации.

    Этап 3: Формат данных YOLOv8 Segmentation

    YOLOv8 требует данные в очень специфическом формате. Если вы используете автоматические конвертеры (как в Roboflow), они сделают это за вас. Но важно понимать структуру «под капотом».

    Для каждого изображения .jpg должен быть создан текстовый файл .txt с тем же именем.

    Внутри файла каждая строка описывает один объект: class_id x1 y1 x2 y2 ... xn yn

    Где: * class_id — целочисленный идентификатор класса (начинается с 0). * x1 y1 ... — координаты вершин полигона. Важно: эти координаты должны быть нормализованы.

    Математика нормализации координат

    Нейросети любят работать с числами в диапазоне от 0 до 1. Абсолютные координаты пикселей (например, ) зависят от разрешения картинки. Чтобы сделать модель независимой от разрешения, мы используем нормализацию.

    Формула нормализации координаты по оси X:

    Где: * — нормализованная координата (от 0 до 1). * — абсолютная координата точки в пикселях (например, 320). * — ширина всего изображения в пикселях (например, 640).

    Формула нормализации координаты по оси Y:

    Где: * — нормализованная координата (от 0 до 1). * — абсолютная координата точки в пикселях (например, 240). * — высота всего изображения в пикселях (например, 480).

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

    Этап 4: Структура датасета

    Чтобы библиотека ultralytics (YOLOv8) поняла ваш датасет, разложите файлы по следующей структуре:

    Разделение данных (Train / Val / Test)

    Никогда не обучайте модель на всех имеющихся данных. Она просто «запомнит» картинки, но не научится узнавать объекты на новых фото. Это называется переобучение (overfitting).

    Классическая пропорция: * 70% — Train (Обучение): На этих примерах сеть учит веса. * 20% — Val (Валидация): На этих примерах сеть проверяет себя после каждой эпохи обучения, чтобы корректировать параметры. * 10% — Test (Тест): «Экзамен» после завершения обучения. Эти картинки сеть не видела никогда.

    Файл data.yaml

    Этот файл связывает пути к папкам и названия классов. Пример содержимого:

    Аугментация данных

    Если у вас мало фотографий (например, всего 50), модель будет работать плохо. Чтобы исправить это, используют аугментацию — искусственное раздувание датасета.

    Методы аугментации: * Flip (Отражение): Зеркальное отражение по горизонтали. * Rotation (Поворот): Поворот на . * Noise (Шум): Добавление зернистости. * Brightness (Яркость): Изменение яркости .

    YOLOv8 имеет встроенные механизмы аугментации во время обучения, поэтому вам не обязательно создавать тысячи копий файлов физически. Достаточно иметь качественный исходный набор, а библиотека сама будет видоизменять картинки «на лету» при подаче в нейросеть.

    Заключение

    Сегодня мы выполнили кропотливую, но необходимую работу. Мы:

  • Написали скрипт для сбора «живых» данных с Raspberry Pi.
  • Разобрали разницу между детекцией и сегментацией.
  • Изучили формат разметки полигонами и математику нормализации координат.
  • Подготовили правильную структуру папок для обучения.
  • Теперь у вас есть готовый датасет. В следующей статье мы перейдем к самому интересному — обучению модели YOLOv8-seg на вашем компьютере (или в облаке Google Colab) и подготовке полученной модели к конвертации для запуска на нейропроцессоре Sony IMX500.

    3. Обучение модели YOLOv8-seg: тренировка, валидация и анализ метрик

    Обучение модели YOLOv8-seg: тренировка, валидация и анализ метрик

    В предыдущих статьях мы подготовили аппаратную платформу Raspberry Pi и собрали качественный датасет, размеченный полигонами. Теперь наступает момент истины: мы превратим набор картинок в «интеллект». В этой статье мы разберем процесс обучения модели сегментации (YOLOv8-seg), научимся читать графики обучения и понимать, насколько хорошо наша нейросеть справляется с задачей.

    Где обучать нейросеть?

    Первый вопрос, который возникает: «Могу ли я обучить модель прямо на Raspberry Pi 4?». Технически — да. Практически — это плохая идея.

    Процесс обучения (training) требует огромных вычислительных мощностей, особенно от видеокарты (GPU). Raspberry Pi отлично справляется с инференсом (запуском уже готовой модели), но обучение на нем займет дни или даже недели, при этом устройство будет работать на пределе температурных возможностей.

    Рекомендуемые варианты:

  • Мощный ПК: Если у вас есть компьютер с видеокартой NVIDIA (RTX 3060 и выше) и установленными драйверами CUDA.
  • Облачные сервисы: Google Colab, Kaggle Kernels или Lambda Labs. Для нашего курса мы будем ориентироваться на Google Colab, так как он предоставляет бесплатный доступ к GPU.
  • Подготовка к обучению

    Мы будем использовать метод Transfer Learning (трансферное обучение). Это подход, при котором мы берем модель, уже обученную на миллионах изображений (например, датасет COCO), и «доучиваем» её на наших специфических данных. Это экономит время и требует меньше данных для достижения высокой точности.

    Установка окружения

    Если вы работаете в Google Colab или на локальном ПК, убедитесь, что библиотека ultralytics установлена:

    Запуск обучения

    Код для запуска обучения предельно прост благодаря удобному API YOLOv8. Создайте файл train.py или ячейку в ноутбуке:

    Разберем ключевые параметры: * epochs (Эпохи): Одна эпоха — это один полный проход нейросети через весь ваш обучающий датасет. 100 эпох — хорошее число для старта. * batch (Батч): Количество изображений, которые сеть обрабатывает за один раз перед обновлением весов. Чем больше видеопамяти, тем больше батч можно ставить. * imgsz: Размер входного изображения. Должен быть кратен 32. Для Raspberry Pi AI Camera оптимально 640.

    Метрики: Как понять, что модель учится?

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

    1. Intersection over Union (IoU)

    Это фундамент оценки качества в компьютерном зрении. IoU показывает, насколько предсказанная маска совпадает с реальной разметкой.

    Формула IoU:

    Где: * — коэффициент пересечения над объединением (от 0 до 1). * — площадь пересечения предсказанной маски и реальной маски (общая область). * — общая площадь, занимаемая обеими масками вместе.

    Если , маски совпали идеально. Если , они вообще не пересекаются.

    !Визуализация принципа расчета метрики Intersection over Union (IoU).

    2. Precision (Точность) и Recall (Полнота)

    Эти две метрики всегда идут в паре и часто находятся в конфликте.

    Precision отвечает на вопрос: «Из всех объектов, которые модель назвала

    4. Конвертация и оптимизация обученной модели для загрузки в процессор IMX500

    Конвертация и оптимизация обученной модели для загрузки в процессор IMX500

    В предыдущей статье мы успешно обучили модель YOLOv8-seg на нашем кастомном датасете. Теперь у нас есть файл весов best.pt. Однако, если вы попытаетесь запустить этот файл напрямую на Raspberry Pi AI Camera, ничего не выйдет.

    Процессор Sony IMX500, встроенный в камеру, не «понимает» формат PyTorch. Более того, он не обладает мощностью настольной видеокарты, чтобы оперировать числами с плавающей запятой (float32) с высокой скоростью. Чтобы наша нейросеть заработала на «железе», нам предстоит пройти процесс конвертации и квантования.

    В этой статье мы превратим нашу тяжелую модель в оптимизированный бинарный файл, готовый к загрузке в NPU (Neural Processing Unit) камеры.

    Почему нельзя использовать .pt файл?

    Файл .pt (PyTorch) — это, по сути, архив, содержащий архитектуру сети и веса в формате чисел с плавающей запятой (FP32).

    Проблемы использования FP32 на граничных устройствах (Edge Devices):

  • Размер: Модели занимают много места.
  • Память: Требуется много оперативной памяти для хранения промежуточных вычислений.
  • Вычисления: Операции с плавающей запятой требуют сложных транзисторных схем и потребляют много энергии.
  • Нейропроцессор внутри IMX500 оптимизирован для работы с целыми числами (Integer), обычно 8-битными (Int8). Это позволяет выполнять вычисления в 4 раза быстрее и потреблять в разы меньше энергии. Наша задача — перевести модель с «языка» математиков (FP32) на «язык» инженеров (Int8).

    !Визуализация этапов трансформации модели от исходного кода до бинарного файла для чипа.

    Теория: Что такое квантование (Quantization)?

    Квантование — это процесс отображения непрерывного диапазона значений (float32) в дискретный набор значений (int8). Представьте, что мы сжимаем линейку длиной в километры (где можно отмерить 1.005 метра) в школьную линейку длиной 25 сантиметров (где есть только целые деления).

    Математически процесс аффинного квантования описывается следующей формулой:

    Где: * (real value) — исходное вещественное число (например, вес нейрона ). * (Scale) — масштабный коэффициент (положительное вещественное число). Он определяет шаг сетки квантования. * (quantized value) — квантованное целочисленное значение (например, ). Для Int8 это число от -128 до 127. * (Zero-point) — целочисленное значение, которое соответствует реальному нулю (). Это позволяет нам точно представлять ноль, что критически важно для нейросетей (так как паддинги и функции активации часто используют ноль).

    Наша цель — найти такие и для каждого слоя нейросети, чтобы потеря точности при переходе от к была минимальной.

    Этап 1: Экспорт в промежуточный формат (ONNX)

    Прежде чем переходить к TFLite или формату Sony, стандартом индустрии является конвертация в ONNX (Open Neural Network Exchange). Это универсальный формат, который понимают практически все фреймворки.

    Однако библиотека ultralytics упрощает нам жизнь и позволяет делать экспорт сразу в TFLite, проходя ONNX «под капотом».

    Этап 2: Post-Training Quantization (PTQ)

    Самый простой способ получить Int8 модель — это пост-тренировочное квантование. Мы берем уже обученную модель и «огрубляем» её веса.

    Но есть нюанс. Если веса (параметры сети) мы можем пересчитать статически, то как быть с активациями (промежуточными данными, которые возникают, когда через сеть проходит картинка)? Их значения зависят от входного изображения.

    Для этого нам нужен Representative Dataset (Калибровочный набор данных). Это небольшая выборка (обычно 100–300 изображений) из нашего тренировочного или валидационного датасета. Конвертер «прогоняет» эти изображения через сеть, замеряет диапазоны значений (min/max) на каждом слое и вычисляет оптимальные параметры и .

    Практика: Экспорт модели с помощью Ultralytics

    Мы будем использовать встроенный метод export библиотеки YOLOv8. Убедитесь, что вы находитесь в виртуальном окружении и у вас установлен файл data.yaml, который мы создавали ранее.

    Создайте файл export_model.py:

    Запустите скрипт:

    Этот процесс может занять несколько минут. В консоли вы увидите логи о том, что происходит калибровка (Calibrating quantization...).

    В результате в папке с весами появится файл best_saved_model/best_int8.tflite (путь может отличаться в зависимости от версии, ищите файл с расширением .tflite).

    Этап 3: Конвертация в формат IMX500 (Blob)

    Полученный файл tflite — это уже квантованная модель. Однако сам сенсор IMX500 требует специфической упаковки прошивки, которая включает в себя модель и инструкции по пост-обработке.

    Для Raspberry Pi AI Camera существует утилита imx500-converter (часть пакета rpicam-apps или устанавливаемая отдельно через инструменты Sony AITRIOS, в зависимости от версии SDK).

    Примечание: Экосистема Raspberry Pi AI Camera активно обновляется. В последних версиях Raspberry Pi OS часто используется подход, где TFLite модель загружается через стандартный API, а драйвер сам занимается передачей инструкций в NPU. Однако для максимальной производительности часто требуется предварительная компиляция.

    Мы рассмотрим общий подход подготовки модели для пайплайна Raspberry Pi.

    Проверка модели

    Перед загрузкой в камеру стоит проверить, насколько сильно упала точность после квантования. Обычно падение mAP (mean Average Precision) на 1-2% считается приемлемым.

    Вы можете валидировать экспортированную модель:

    Если точность упала катастрофически (например, до 0), значит:

  • Калибровочный датасет был некачественным.
  • Вы забыли нормализовать изображения при калибровке (YOLOv8 делает это автоматически, но при ручном экспорте это частая ошибка).
  • Оптимизация ввода/вывода

    IMX500 имеет жесткие ограничения на формат входных и выходных данных.

  • Вход (Input): Обычно это тензор размером (если мы обучали на 640). Формат цвета часто RGB, но сенсор может выдавать YUV. Драйвер камеры обычно берет на себя конвертацию YUV -> RGB перед подачей в NPU.
  • Выход (Output): Модель сегментации YOLOv8 выдает два типа данных:
  • * Боксы и классы. * Прототипы масок (Proto masks).

    Обработка выхода сегментации — самая ресурсоемкая часть. В «сыром» виде модель выдает набор коэффициентов масок. Сборка финальной картинки (наложение маски на изображение) должна происходить на CPU Raspberry Pi, так как NPU выдает только тензоры.

    Формула восстановления маски из выхода нейросети:

    Где: * — итоговая маска. * — сигмоида (функция активации). * — прототипы масок (выход высокого разрешения). * — коэффициенты масок для конкретного обнаруженного объекта.

    Эту операцию нам придется реализовывать (или использовать готовую реализацию из ultralytics) в скрипте инференса, который мы напишем в следующей статье.

    Заключение

    Сегодня мы преодолели «языковой барьер» между фреймворком обучения и аппаратным ускорителем. Мы:

  • Разобрали математику квантования и поняли роль калибровочного датасета.
  • Экспортировали модель YOLOv8-seg в формат TFLite Int8.
  • Подготовили базу для запуска модели на реальном устройстве.
  • Теперь у вас есть файл best_int8.tflite. Это «мозг» вашей камеры. В следующей, финальной статье курса, мы напишем Python-скрипт, который будет захватывать видеопоток с Raspberry Pi AI Camera, отправлять его в NPU, получать результаты сегментации и визуализировать их в реальном времени.

    5. Разработка ПО на Python: получение и обработка метаданных с камеры

    Разработка ПО на Python: получение и обработка метаданных с камеры

    Мы подошли к финальному и самому захватывающему этапу нашего курса. У нас есть Raspberry Pi 4, подключенная AI Camera с сенсором IMX500, и файл модели best_int8.tflite, который мы с таким трудом подготовили и квантовали. Но сама по себе модель внутри камеры — это просто набор весов. Чтобы увидеть результат, нам нужно написать программное обеспечение, которое будет «общаться» с камерой, забирать результаты работы нейросети и превращать их в понятную человеку картинку.

    В этой статье мы создадим Python-скрипт для инференса (запуска) модели в реальном времени. Мы разберем, как извлечь тензоры из потока метаданных, как декодировать выходные данные YOLOv8 и как нарисовать маски сегментации на видеопотоке.

    Архитектура потока данных

    Прежде чем писать код, важно понять, как данные перемещаются внутри нашей системы. В отличие от обычной веб-камеры, где мы просто получаем картинку, Raspberry Pi AI Camera генерирует два параллельных потока данных:

  • Видеопоток (Pixel Data): Обычное изображение (например, YUV или RGB), которое мы видим на экране.
  • Метаданные (Metadata): Результаты работы нейропроцессора (NPU). Это сырые байты, представляющие собой выходные тензоры нашей модели.
  • !Схема разделения видеопотока и потока метаданных нейросети

    Наша задача — синхронизировать эти два потока. Мы должны взять кадр и наложить на него именно те предсказания, которые были сделаны для этого конкретного момента времени.

    Инструментарий: Picamera2 и NumPy

    Для работы с камерой на низком уровне в Python мы будем использовать библиотеку Picamera2. Это официальная библиотека для Raspberry Pi OS (Bookworm), которая предоставляет доступ к подсистеме libcamera.

    Для математических операций нам понадобится NumPy. Обработка массивов данных на чистом Python слишком медленная для реального времени. NumPy позволяет выполнять векторные операции на порядки быстрее.

    Установите необходимые зависимости, если они отсутствуют:

    Загрузка модели в камеру

    В отличие от запуска на CPU, где мы загружаем модель в оперативную память компьютера, здесь мы должны загрузить модель непосредственно в память сенсора IMX500. Это делается на этапе инициализации камеры.

    В скрипте конфигурации Picamera2 мы указываем путь к нашему файлу .tflite. Драйвер камеры автоматически парсит этот файл, загружает его в DSP камеры и настраивает конвейер обработки.

    Разбор выходных данных YOLOv8 Segmentation

    Самая сложная часть — это интерпретация того, что возвращает камера. Модель YOLOv8-seg имеет два основных выхода (Output Heads):

  • Detection Head: Содержит координаты рамок (Bounding Boxes), вероятности классов и коэффициенты масок.
  • Proto Head: Содержит прототипы масок (Prototype Masks).
  • Математика восстановления маски

    Чтобы получить итоговую маску для конкретного объекта, мы должны совершить матричное умножение прототипов масок на коэффициенты масок этого объекта. Это линейная комбинация прототипов.

    Формула вычисления маски:

    Где: * — итоговая матрица маски (размером пикселей). * — функция активации Сигмоида. Она превращает значения в диапазон от 0 до 1. * — матрица прототипов (размером , где — количество пикселей в прототипе, ). * — транспонированный вектор коэффициентов маски для конкретного объекта (размером ).

    После вычисления , мы получаем «мягкую» маску. Чтобы сделать её бинарной (объект/фон), мы применяем пороговое значение (обычно 0.5):

    Где: * — итоговое значение пикселя (1 — объект есть, 0 — фона нет). * — значение из предыдущей формулы. * — порог уверенности.

    Реализация на Python

    Давайте напишем структуру кода для обработки. Мы опустим код инициализации Picamera2 (он стандартен и доступен в документации), и сосредоточимся на функции обработки метаданных.

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

    1. Постобработка детекций (Non-Maximum Suppression)

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

    2. Генерация масок

    Теперь самое интересное — реализация формулы .

    Оптимизация производительности

    Python — интерпретируемый язык, и циклы for в нем работают медленно. В примере выше мы обрабатываем каждый объект в цикле. Если объектов 50, это создаст задержку (лаг).

    Чтобы ускорить процесс, нужно использовать матричные операции NumPy для обработки всех масок одновременно.

    Вместо умножения coeff (1 объект) на protos, мы можем собрать коэффициенты всех объектов в матрицу размером и выполнить одно умножение:

    Где: * — тензор, содержащий маски для всех найденных объектов сразу. * — матрица коэффициентов всех обнаруженных объектов. * — матрица прототипов.

    Это сократит время обработки с 50-100 мс до 5-10 мс, что критически важно для получения плавного видео 30 FPS.

    Визуализация

    Последний штрих — наложение полупрозрачных цветных масок на видео.

    Заключение курса

    Поздравляю! Вы прошли путь от распаковки Raspberry Pi до создания собственной системы компьютерного зрения с аппаратным ускорением.

    Мы научились:

  • Настраивать окружение для Edge AI.
  • Собирать и размечать уникальные датасеты.
  • Обучать современные модели сегментации (YOLOv8).
  • Квантовать модели для работы на нейропроцессорах.
  • Писать высокопроизводительный код на Python для обработки тензоров.
  • Теперь в ваших руках мощный инструмент. Вы можете создать умную кормушку для птиц, робота-сортировщика мусора, систему контроля качества на производстве или дрон, облетающий препятствия. Мир Edge AI открыт для ваших идей!