Обнаружение объектов на Python: от каскадов до YOLO

Раздел: Прикладные задачи -> Компьютерное зрение

Основные подходы к распознаванию объектов на Python

Самое эффективное решение: нейросетевая детекция с YOLOv8

На сегодняшний день наиболее производительным и точным методом является использование модели YOLO (You Only Look Once) версии 8 из библиотеки Ultralytics. YOLOv8 обеспечивает высокую скорость инференса при отличной точности, поддерживает GPU и CPU, а также предоставляет простой API.

Как выполнить распознавание объектов с помощью YOLOv8 на Python?

Установка библиотеки выполняется через pip. После загрузки предобученной модели достаточно двух строк кода для детекции на изображении.


# Установка (один раз)
pip install ultralytics

# Простейший скрипт детекции
from ultralytics import YOLO

model = YOLO('yolov8n.pt')  # модель nano – быстрая и лёгкая
results = model('image.jpg')
results[0].show()           # отображение результата
  

Python opencv functions (функции opencv в python)

Результат – изображение с нарисованными рамками и подписями классов. Для работы с видео или веб-камерой используется аналогичный вызов с путём к видеофайлу или числом 0 для камеры.

Типичные проблемы и их решения:

  • Ошибка импорта Ultralytics. Возникает, если не установлены зависимости (PyTorch). Решение: установить PyTorch вручную с сайта pytorch.org, затем ultralytics.
  • CUDA out of memory. Модель требует больше видеопамяти, чем доступно. Выберите более лёгкую версию (yolov8n вместо yolov8x) или уменьшите размер входного изображения.
  • Низкая точность на своих данных. Предобученная модель может плохо распознавать специфические объекты. Требуется дообучение (fine‑tuning) на собственном датасете.

Цели использования: быстрая интеграция детекции в производственные системы, прототипирование, обработка потокового видео в реальном времени.

Вариант 1. Как распознавать объекты с помощью каскадов Хаара (Haar Cascades) из OpenCV?

Классический метод, не требующий нейронных сетей. Используется для детекции лиц, глаз, номеров автомобилей. Работает быстро на CPU.


import cv2

# Загрузка каскада для лиц
face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_frontalface_default.xml')

img = cv2.imread('people.jpg')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
faces = face_cascade.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=5)
for (x, y, w, h) in faces:
    cv2.rectangle(img, (x, y), (x+w, y+h), (255, 0, 0), 2)
cv2.imshow('Detected', img)
cv2.waitKey(0)
  

Python opencv 215 assertion failed (ошибка assertion в opencv python)

Частые ошибки:

  • Файл каскада не найден. Убедитесь, что путь корректен. Можно указать абсолютный путь.
  • Ложные срабатывания при низком значении minNeighbors. Увеличьте его до 6-8.
  • Каскады не распознают объекты под углом. Для поворотов требуется отдельное обучение.

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

Вариант 2. Как использовать OpenCV DNN с предобученными моделями (SSD MobileNet)?

OpenCV может загружать модели, обученные в других фреймворках (Caffe, TensorFlow). Например, SSD MobileNet – лёгкая сеть для 80 классов.


import cv2

net = cv2.dnn.readNetFromCaffe('MobileNetSSD_deploy.prototxt', 'MobileNetSSD_deploy.caffemodel')
img = cv2.imread('street.jpg')
h, w = img.shape[:2]
blob = cv2.dnn.blobFromImage(img, 0.007843, (300, 300), 127.5)
net.setInput(blob)
detections = net.forward()

for i in range(detections.shape[2]):
    confidence = detections[0, 0, i, 2]
    if confidence > 0.5:
        class_id = int(detections[0, 0, i, 1])
        box = detections[0, 0, i, 3:7] * np.array([w, h, w, h])
        # отрисовка ...
  

Python изображения (работа с изображениями в python)

Проблемы: файлы .prototxt и .caffemodel нужно скачать отдельно. При несовпадении размеров входного изображения модель может выдавать ошибку. Используйте blobFromImage с параметрами, совпадающими с обучением.

Цели: использование готовых моделей без установки глубоких фреймворков, подходит для встраиваемых систем.

Вариант 3. Как сделать детекцию с помощью TensorFlow Object Detection API?

Это мощный фреймворк от Google, поддерживающий множество архитектур (Faster R‑CNN, SSD, EfficientDet). Требует установки TensorFlow и дополнительных пакетов.


import tensorflow as tf
import tensorflow_hub as hub

model = hub.load('https://tfhub.dev/tensorflow/faster_rcnn/resnet152_v1_640x640/1')
image = tf.io.read_file('image.jpg')
image = tf.image.decode_jpeg(image, channels=3)
image = tf.expand_dims(image, axis=0)
detections = model(image)
# извлечение bounding boxes и классов
  

библиотека cv2 python (библиотека opencv в python)

Типичные ошибки: несовместимость версий TensorFlow и TensorFlow Hub, медленная загрузка модели из интернета, необходимость преобразования тензоров для визуализации.

Цели: эксперименты с разными архитектурами, обучение собственных моделей на больших датасетах, интеграция в пайплайны TensorFlow.

Вариант 4. Как применить Detectron2 от Facebook AI?

Фреймворк на PyTorch, известный высокой точностью. Подходит для исследовательских задач.


from detectron2 import model_zoo
from detectron2.engine import DefaultPredictor
from detectron2.config import get_cfg

cfg = get_cfg()
cfg.merge_from_file(model_zoo.get_config_file('COCO-Detection/retinanet_R_50_FPN_1x.yaml'))
cfg.MODEL.WEIGHTS = model_zoo.get_checkpoint_url('COCO-Detection/retinanet_R_50_FPN_1x.yaml')
predictor = DefaultPredictor(cfg)
outputs = predictor(image)
  

Проблемы: сложная установка (зависимости, компиляция CUDA), большой размер моделей, высокие требования к памяти.

Цели: получение state‑of‑the‑art результатов, научные исследования, сегментация экземпляров (Instance Segmentation).

Заключение

Выбор метода зависит от задачи: YOLOv8 – универсальный и быстрый, OpenCV каскады – для простых детекций, TensorFlow и Detectron2 – для глубоких исследований. Используйте примеры кода как отправную точку.

Расширенные примеры распознавания объектов

Пример 1: Дообучение YOLOv8 на кастомном датасете

Создайте структуру папок с изображениями и аннотациями в формате YOLO (.txt). Затем выполните обучение.

Пример

from ultralytics import YOLO

# Загрузка предобученной модели
model = YOLO('yolov8n.pt')

# Обучение на своих данных (датасет лежит в папке dataset)
results = model.train(data='dataset/data.yaml', epochs=50, imgsz=640, batch=8)

Результат: после обучения появляется папка runs/detect/train с весами best.pt. Тестирование:

Пример

model = YOLO('runs/detect/train/weights/best.pt')
results = model('test.jpg')
results[0].show()
[INFO] image 1/1: 640x640 3 persons, 1 car, 1 dog
Скорость: 45ms

Пример 2: Экспорт YOLOv8 в ONNX для ускорения на CPU

ONNX позволяет запускать модель без PyTorch, используя оптимизированные рантаймы (ONNX Runtime).

Пример

model = YOLO('yolov8n.pt')
model.export(format='onnx')  # создаст файл yolov8n.onnx

Загрузка ONNX модели в другом скрипте:

Пример

import onnxruntime as ort
import numpy as np
from PIL import Image

ort_session = ort.InferenceSession('yolov8n.onnx')
image = Image.open('test.jpg').resize((640, 640))
input_tensor = np.array(image).astype(np.float32) / 255.0
input_tensor = input_tensor.transpose(2, 0, 1)[np.newaxis, ...]
outputs = ort_session.run(None, {'images': input_tensor})
# обработка результатов ...
Инференс: 28ms (против 45ms на исходном PyTorch)

Пример 3: Использование TFLite для Raspberry Pi

Подготовка модели для мобильных устройств. Сначала экспорт в TF‑SavedModel, затем преобразование.

Пример

model = YOLO('yolov8n.pt')
model.export(format='saved_model')  # сохранит в папку yolov8n_saved_model

import tensorflow as tf
converter = tf.lite.TFLiteConverter.from_saved_model('yolov8n_saved_model')
tflite_model = converter.convert()
with open('yolov8n.tflite', 'wb') as f:
    f.write(tflite_model)

Запуск на Raspberry Pi:

Пример

import tflite_runtime.interpreter as tflite
interpreter = tflite.Interpreter(model_path='yolov8n.tflite')
interpreter.allocate_tensors()
# аналогично загрузке ONNX

Пример 4: Детекция с OpenCV DNN + YOLOv3 (альтернатива)

Хотя YOLOv8 удобнее, иногда требуется использовать старую YOLOv3 с OpenCV.

Пример

net = cv2.dnn.readNet('yolov3.weights', 'yolov3.cfg')
layer_names = net.getLayerNames()
output_layers = [layer_names[i[0] - 1] for i in net.getUnconnectedOutLayers()]

blob = cv2.dnn.blobFromImage(img, 1/255.0, (416, 416), swapRB=True, crop=False)
net.setInput(blob)
outputs = net.forward(output_layers)

# разбор выходов ...
Обнаружено 3 объекта: person (0.89), car (0.76), bus (0.62)

Пример 5: Пакетная обработка папки изображений с YOLOv8

Пример

import glob
from ultralytics import YOLO

model = YOLO('yolov8n.pt')
images = glob.glob('input_folder/*.jpg')
results = model(images, save=True, project='output_folder')

После выполнения в output_folder появятся изображения с детекциями и текстовые файлы с координатами.

Пример 6: Фильтрация по классу и получение координат

Пример

results = model('street.jpg')
for r in results:
    boxes = r.boxes
    for box in boxes:
        cls = int(box.cls[0])
        if cls == 0:  # класс 'person'
            x1, y1, x2, y2 = box.xyxy[0].tolist()
            print(f'Person at {x1:.0f},{y1:.0f},{x2:.0f},{y2:.0f}')
Person at 124,56,310,420
Person at 512,100,680,480

Распознавание объектов с помощью Python - comments

En
распознавание объектов python (python)