Мастер-класс: Цифровое зрение с YOLO

Пошаговое руководство по компьютерному зрению и распознаванию объектов

1
2
3
4
5
6
7
8

Добро пожаловать в мир компьютерного зрения!

Исследуем как работает YOLO для распознавания объектов

Что такое компьютерное зрение?

Компьютерное зрение — это область искусственного интеллекта, которая позволяет компьютерам "видеть" и понимать визуальный мир, подобно тому, как это делают люди.

Исходное изображение
Оригинальное изображение

Изображение до обработки

Результат YOLO
Результат детекции

Объекты с рамками и метками

YOLO v3 Python OpenCV Нейронные сети

Скачайте материалы для мастер-класса

Получите все необходимые файлы для запуска проекта на вашем компьютере

Шаг 1: Подключение библиотек

Подготовка инструментов для работы

import
cv2
import
numpy
as
np
from
matplotlib
import
pyplot
as
plt
import
time
import
sys
import
os

# 🔧 Что подключаем и зачем:
# cv2 - Работа с изображениями и видео
# np - Быстрые вычисления с массивами
# plt - Визуализация графиков и изображений
# time - Работа со временем и задержками
# os - Работа с файловой системой

Подготовка рабочего места

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

OpenCV (cv2) — основная библиотека для компьютерного зрения, предоставляет инструменты для обработки изображений и видео.

NumPy (np) — библиотека для работы с многомерными массивами и математическими операциями, необходима для эффективной обработки данных изображений.

Matplotlib (plt) — используется для визуализации результатов, позволяет отображать изображения и графики прямо в ноутбуке.

Дополнительные утилиты — time для измерения производительности, os для работы с файлами и директориями.

Установка необходимых библиотек

Для работы проекта необходимо установить следующие библиотеки:

# Установка через pip
pip install opencv-python
pip install numpy
pip install matplotlib
pip install jupyterlab

Шаг 2: Настройка параметров

Конфигурация нейронной сети YOLO

# ⚙️ Настройки нейронной сети

CONFIDENCE = 0.5 # Минимальная уверенность
SCORE_THRESHOLD = 0.5 # Порог важности
IOU_THRESHOLD = 0.5 # Порог перекрытия

# 🧠 Загрузка нейронной сети
config_path = "cfg/yolov3.cfg"
weights_path = "yolov3.weights"

# 📋 Список объектов
labels = open("data/coco.names").read().strip().split("\n")
colors = np.random.randint(0, 255, size=(len(labels), 3), dtype="uint8")

Конфигурация YOLO

На этом этапе мы настраиваем параметры нейронной сети и загружаем необходимые файлы для работы с YOLO (You Only Look Once).

Пороги уверенности:
CONFIDENCE = 0.5 означает, что мы доверяем только тем предсказаниям, в которых модель уверена более чем на 50%. Это помогает отфильтровать ложные срабатывания.

Файлы модели:
yolov3.cfg — конфигурационный файл, описывающий архитектуру нейронной сети
yolov3.weights — веса модели, содержащие обученные параметры
coco.names — список из 80 классов объектов, которые может распознавать YOLO

Цвета для визуализации:
Генерируем случайные RGB-цвета для каждого класса объектов, чтобы визуально отличать разные типы обнаруженных объектов.

Шаг 3: Загрузка нейронной сети

Инициализация модели YOLO

# 🔧 Загружаем нейронную сеть YOLO
net = cv2.dnn.readNetFromDarknet(config_path, weights_path)

# 🖼️ Загрузка и отображение изображения
path_name = "images/tu.jpg"
image = cv2.imread(path_name)
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
plt.imshow(image)

Инициализация модели

Теперь мы загружаем предварительно обученную модель YOLO в память и готовим изображение для анализа.

Загрузка сети:
Используем функцию cv2.dnn.readNetFromDarknet() для загрузки модели YOLO из файлов конфигурации и весов. Это создает объект нейронной сети, готовый к работе.

Загрузка изображения:
cv2.imread() загружает изображение с диска в формате BGR (Blue-Green-Red)
cv2.cvtColor() преобразует цветовое пространство из BGR в RGB, так как OpenCV использует BGR по умолчанию, а большинство других библиотек — RGB
plt.imshow() отображает изображение для визуальной проверки

Важно понимать разницу между цветовыми пространствами BGR и RGB, так как неправильное преобразование может привести к искажению цветов на изображении.

Шаг 4: Подготовка изображения

Преобразование для нейронной сети

# 📦 Подготовка изображения для нейросети
h, w = image.shape[:2] # Получаем высоту и ширину

# Создаем 4D-объект (blob) для нейросети:
blob = cv2.dnn.blobFromImage(
    image,
    1/255.0, # Нормализуем цвета (0..255 → 0..1)
    (416, 416), # Изменяем размер до 416x416
    swapRB=False, # Не меняем R и B местами
    crop=False) # Не обрезаем, а масштабируем

# 🔍 Проверка форматов
print("image.shape:", image.shape)
print("blob.shape:", blob.shape)

Преобразование изображения

Нейронные сети требуют специального формата входных данных. Мы преобразуем изображение в "blob" — специальный 4D-тензор, подходящий для обработки нейросетью.

Процесс преобразования:
1. Нормализация: делим значения пикселей на 255, чтобы привести их к диапазону [0,1]. Это улучшает обучение и работу нейросети.
2. Изменение размера: YOLO требует входные изображения размером 416×416 пикселей. Мы масштабируем изображение до этого размера.
3. Создание blob: формируем 4D-тензор с формой (1, 3, 416, 416), где:
  • 1 — количество изображений в пакете (batch size)
  • 3 — количество цветовых каналов (RGB)
  • 416×416 — размер изображения

Этот процесс называется "предобработкой" и является критически важным для правильной работы нейронной сети.

Шаг 5: Анализ изображения

Прогнозирование с помощью нейросети

# ⚙️ Передача данных в нейросеть
net.setInput(blob) # Подаем изображение на вход
ln = net.getLayerNames() # Получаем имена всех слоев

# Получаем имена выходных слоев
try:
    ln = [ln[i[0] - 1] for i in net.getUnconnectedOutLayers()]
except IndexError:
    ln = [ln[i - 1] for i in net.getUnconnectedOutLayers()]

start = time.perf_counter() # Запускаем таймер
layer_outputs = net.forward(ln) # Выполняем анализ
time_took = time.perf_counter() - start # Останавливаем таймер
print(f"Time took: {time_took:.2f}s")

Прогнозирование нейросетью

Теперь мы передаем подготовленное изображение в нейронную сеть и получаем результаты анализа.

Процесс анализа:
1. Установка входных данных: используем net.setInput() для передачи blob в сеть
2. Определение выходных слоев: YOLO имеет несколько выходных слоев, каждый из которых отвечает за обнаружение объектов разного размера
3. Выполнение прямого прохода: вызываем net.forward() для получения предсказаний сети

Структура выходных данных:
Каждое обнаружение содержит 85 значений:
• 4 координаты (x, y, ширина, высота)
• 1 значение уверенности (confidence)
• 80 вероятностей для каждого из классов COCO

Время выполнения (обычно 1-3 секунды) зависит от мощности процессора и размера изображения. На GPU этот процесс значительно быстрее.

Шаг 6: Обработка результатов

Извлечение и фильтрация обнаруженных объектов

# 🧹 Обработка результатов нейросети
boxes, confidences, class_ids = [], [], []
for output in layer_outputs: # Для каждого выхода сети
    for detection in output: # Для каждого найденного объекта
        scores = detection[5:] # Вероятности классов
        class_id = np.argmax(scores) # Класс с наибольшей вероятностью
        confidence = scores[class_id] # Уверенность в предсказании
        if confidence > CONFIDENCE: # Если выше порога
            box = detection[:4] * np.array([w, h, w, h]) # Масштабируем координаты
            (centerX, centerY, width, height) = box.astype("int")
            x = int(centerX - (width / 2))
            y = int(centerY - (height / 2))
            boxes.append([x, y, int(width), int(height)])
            confidences.append(float(confidence))
            class_ids.append(class_id)

Обработка предсказаний

На этом этапе мы извлекаем полезную информацию из "сырых" выходов нейронной сети и фильтруем результаты.

Процесс обработки:
1. Извлечение данных: для каждого обнаружения извлекаем координаты, уверенность и идентификатор класса
2. Фильтрация по уверенности: оставляем только те обнаружения, где уверенность превышает порог (0.5)
3. Масштабирование координат: преобразуем координаты из размера 416×416 обратно к размеру исходного изображения

Ключевые преобразования:
• Координаты центра (centerX, centerY) преобразуются в координаты верхнего левого угла (x, y)
• Ширина и высота масштабируются в соответствии с размером исходного изображения
• Идентификатор класса определяется как аргумент максимального значения среди 80 вероятностей

На этом этапе мы получаем три списка: координаты рамок, уровни уверенности и идентификаторы классов — все необходимое для визуализации результатов.

Шаг 7: Визуализация результатов

Отображение обнаруженных объектов

# 🖍️ Отрисовка рамок и подписей
for i in range(len(boxes)):
    x, y = boxes[i][0], boxes[i][1]
    w, h = boxes[i][2], boxes[i][3]
    color = [int(c) for c in colors[class_ids[i]]]
    cv2.rectangle(image, (x, y), (x + w, y + h), color=color, thickness=2)

    text = f"{labels[class_ids[i]]}: {confidences[i]:.2f}"
    (text_width, text_height) = cv2.getTextSize(text, cv2.FONT_HERSHEY_SIMPLEX,
            fontScale=1, thickness=2)[0]
    overlay = image.copy()
    cv2.rectangle(overlay, (x, y - 30), (x + text_width, y), color=color, thickness=-1)
    image = cv2.addWeighted(overlay, 0.6, image, 0.4, 0)
    cv2.putText(image, text, (x, y - 5), cv2.FONT_HERSHEY_SIMPLEX,
            fontScale=1, color=(0, 0, 0), thickness=2)

# 🧹 Удаление дублирующих рамок (NMS)
idxs = cv2.dnn.NMSBoxes(boxes, confidences, SCORE_THRESHOLD, IOU_THRESHOLD)

Визуализация результатов

Финальный этап — отображение обнаруженных объектов на изображении с помощью рамок и подписей.

Процесс визуализации:
1. Рисование рамок: для каждого обнаруженного объекта рисуем прямоугольник соответствующего цвета
2. Добавление подписей: отображаем название класса и уровень уверенности над рамкой
3. Фон для текста: создаем полупрозрачный фон под текстом для лучшей читаемости
4. Удаление дубликатов: применяем алгоритм NMS (Non-Maximum Suppression) для удаления перекрывающихся рамок

Non-Maximum Suppression (NMS):
Этот алгоритм решает проблему множественных рамок вокруг одного объекта. Он:
• Сортирует рамки по уровню уверенности
• Выбирает рамку с наивысшей уверенностью
• Удаляет все остальные рамки, которые сильно перекрываются с выбранной (IOU > 0.5)
• Повторяет процесс для оставшихся рамок

Результат — чистое изображение с одним прямоугольником для каждого обнаруженного объекта и информативными подписями.

Заключение и дальнейшие шаги

Подведение итогов и возможности развития

Итоги мастер-класса

Мы успешно реализовали полный цикл работы с нейронной сетью YOLO для распознавания объектов на изображениях.

Полный процесс
Процесс YOLO

От загрузки изображения до визуализации результатов

Достигнутые цели:

  • Подключение и настройка необходимых библиотек
  • Загрузка и инициализация модели YOLO
  • Подготовка изображения для анализа
  • Выполнение анализа с помощью нейросети
  • Обработка и визуализация результатов

Дальнейшие возможности:

  • Обработка видео в реальном времени
  • Интеграция с веб-приложениями
  • Обучение на собственных данных
  • Оптимизация для мобильных устройств
  • Создание систем безопасности и мониторинга

Полный пакет материалов

Скачайте все необходимые файлы для продолжения работы с проектом

YOLO v3 Python OpenCV Нейронные сети