OpenCV и Python: создание приложений компьютерного зрения с нуля

Пройдите тест, узнайте какой профессии подходите
Сколько вам лет
0%
До 18
От 18 до 24
От 25 до 34
От 35 до 44
От 45 до 49
От 50 до 54
Больше 55

Для кого эта статья:

  • Разработчики и программисты, интересующиеся компьютерным зрением
  • Студенты и начинающие специалисты в области IT, изучающие Python
  • Профессионалы и эксперты, желающие расширить свои знания о библиотеке OpenCV и ее приложениях

    Компьютерное зрение перестало быть уделом избранных технических гигантов. Благодаря OpenCV и Python разработчики любого уровня получили мощный инструментарий для создания приложений, способных "видеть" мир. От простого размытия фотографий до сложных систем распознавания лиц и объектов — всё это стало доступно с помощью нескольких строк кода. В этом руководстве мы препарируем основные возможности библиотеки cv2, покажем готовые решения типичных задач и заложим фундамент для ваших собственных проектов компьютерного зрения. 🔍

Осваиваете Python и хотите погрузиться в увлекательный мир компьютерного зрения? Обучение Python-разработке от Skypro предлагает курсы, где вы научитесь не только базовым принципам программирования, но и продвинутым техникам работы с OpenCV. Вы сможете создавать собственные проекты по распознаванию объектов и обработке изображений под руководством практикующих экспертов. Превратите свое увлечение в востребованную профессию!

OpenCV и Python: основы и установка библиотеки cv2

OpenCV (Open Source Computer Vision Library) — это библиотека с открытым исходным кодом, созданная для решения задач компьютерного зрения. Что такое opencv? Это набор алгоритмов и инструментов, позволяющих компьютеру "видеть" и анализировать изображения почти как человек. В сочетании с Python библиотека становится невероятно мощным и доступным инструментом для разработчиков.

Для начала работы с OpenCV необходимо установить библиотеку opencv-python. Самый простой способ — использовать pip:

Bash
Скопировать код
pip install opencv-python

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

Bash
Скопировать код
pip install opencv-contrib-python

После установки можно импортировать библиотеку в Python-скрипт:

Python
Скопировать код
import cv2

Проверить установленную версию можно с помощью:

Python
Скопировать код
print(cv2.__version__)

Важно понимать основные концепции работы с изображениями в OpenCV:

Концепция Описание Пример в коде
Изображение как массив Изображения представлены как многомерные NumPy-массивы img.shape вернёт (height, width, channels)
Координатная система Начало координат (0,0) в левом верхнем углу img[y, x] для доступа к пикселю
Цветовые пространства По умолчанию изображения загружаются в BGR (не RGB!) cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
Память и ресурсы Необходимо освобождать ресурсы после работы cv2.destroyAllWindows()

Библиотека opencv работает с различными типами изображений и видео. Основные поддерживаемые форматы:

  • Растровые изображения: JPEG, PNG, TIFF, BMP
  • Видеоформаты: MP4, AVI, MPEG
  • Потоковое видео с камеры

Базовый цикл работы с opencv-python включает несколько этапов:

  1. Загрузка или захват изображения/видео
  2. Предобработка (изменение размера, фильтрация и т.д.)
  3. Применение алгоритмов компьютерного зрения
  4. Отображение или сохранение результатов
  5. Освобождение ресурсов

Александр Петров, инженер компьютерного зрения Мой путь в мир компьютерного зрения начался с банального вопроса: "Как автоматизировать сортировку фотографий по содержимому?" В поисках решения я наткнулся на OpenCV и Python. Начинал я с нуля — даже не знал, что такое open cv. Установка библиотеки казалась сложной, и первые две попытки завершились ошибками. Оказалось, что на Windows нужно было установить правильную версию Visual C++ и решить конфликты зависимостей.

Когда я наконец запустил свой первый скрипт, открывающий изображение, это было как первый шаг на Луну. Через месяц экспериментов я создал простую программу, распознающую лица на фотографиях и автоматически сортирующую их по папкам. Сейчас эта система обрабатывает тысячи изображений в нашем архиве, а начиналось всё с простой команды pip install opencv-python.

Пошаговый план для смены профессии

Базовые операции с изображениями через OpenCV-Python

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

Для загрузки изображения используется функция python cv2 imread:

Python
Скопировать код
import cv2
# Загрузка изображения
img = cv2.imread('image.jpg')

По умолчанию изображение загружается в цветовом пространстве BGR. Если нужно загрузить его в оттенках серого, используем флаг:

Python
Скопировать код
img_gray = cv2.imread('image.jpg', cv2.IMREAD_GRAYSCALE)

Для отображения изображения используем функцию:

Python
Скопировать код
cv2.imshow('Image', img)
cv2.waitKey(0) # Ожидание нажатия клавиши
cv2.destroyAllWindows() # Закрытие всех окон

Сохранение обработанного изображения выполняется с помощью cv2 imwrite:

Python
Скопировать код
cv2.imwrite('processed_image.jpg', img)

Теперь рассмотрим основные операции с изображениями:

  1. Изменение размера:
Python
Скопировать код
resized_img = cv2.resize(img, (width, height))
# Или с сохранением соотношения сторон:
scale_percent = 50 # процент от исходного размера
new_width = int(img.shape[1] * scale_percent / 100)
new_height = int(img.shape[0] * scale_percent / 100)
resized_img = cv2.resize(img, (new_width, new_height))

  1. Обрезка изображения:
Python
Скопировать код
# Вырезание региона [y:y+h, x:x+w]
cropped_img = img[100:300, 200:400]

  1. Конвертация цветовых пространств:
Python
Скопировать код
# BGR в RGB
rgb_img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
# BGR в оттенки серого
gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# BGR в HSV (тон, насыщенность, яркость)
hsv_img = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)

  1. Рисование на изображениях:
Python
Скопировать код
# Рисование прямоугольника
cv2.rectangle(img, (x1, y1), (x2, y2), (0, 255, 0), 2)
# Рисование круга
cv2.circle(img, (center_x, center_y), radius, (0, 0, 255), 2)
# Добавление текста
cv2.putText(img, 'Hello OpenCV', (x, y), cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 0, 0), 2)

Работа с пикселями — еще одна базовая операция. Изображение в OpenCV представлено как NumPy-массив, что позволяет легко манипулировать отдельными пикселями:

Python
Скопировать код
# Получение значения пикселя (для BGR изображения)
px = img[100, 100]
# Изменение значения пикселя
img[100, 100] = [255, 0, 0] # Устанавливаем синий цвет

Доступ к свойствам изображения:

Python
Скопировать код
# Получение размеров изображения
height, width, channels = img.shape
# Для изображения в оттенках серого
height, width = gray_img.shape

Операция Функция OpenCV Сложность Типичное применение
Загрузка изображения cv2.imread() Низкая Начало любой обработки
Отображение cv2.imshow() Низкая Визуализация результатов
Изменение размера cv2.resize() Низкая Подготовка для нейросетей
Поворот cv2.rotate() Средняя Коррекция ориентации
Изменение цветового пространства cv2.cvtColor() Низкая Подготовка к обработке

Также стоит упомянуть о работе с видео и веб-камерой:

Python
Скопировать код
# Чтение видео из файла
cap = cv2.VideoCapture('video.mp4')
# Или захват с веб-камеры (0 – индекс первой камеры)
cap = cv2.VideoCapture(0)

while True:
ret, frame = cap.read() # ret = True, если кадр прочитан успешно
if not ret:
break

# Обработка кадра
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

# Отображение результата
cv2.imshow('Video', gray)

# Выход при нажатии клавиши 'q'
if cv2.waitKey(1) & 0xFF == ord('q'):
break

cap.release()
cv2.destroyAllWindows()

Трансформация и фильтрация изображений в OpenCV

Трансформация и фильтрация изображений — основные операции для подготовки данных к анализу. Рассмотрим наиболее распространённые методы, которые предоставляет opencv-python документация.

Начнём с базовых геометрических преобразований:

  1. Вращение:
Python
Скопировать код
# Вращение изображения на 45 градусов
rows, cols = img.shape[:2]
M = cv2.getRotationMatrix2D((cols/2, rows/2), 45, 1)
rotated = cv2.warpAffine(img, M, (cols, rows))

  1. Перспективные преобразования:
Python
Скопировать код
# Исходные точки
pts1 = np.float32([[56,65],[368,52],[28,387],[389,390]])
# Целевые точки (прямоугольник)
pts2 = np.float32([[0,0],[300,0],[0,300],[300,300]])
# Матрица трансформации
M = cv2.getPerspectiveTransform(pts1, pts2)
# Применение трансформации
warped = cv2.warpPerspective(img, M, (300, 300))

  1. Аффинные преобразования:
Python
Скопировать код
# Смещение, масштабирование, вращение
rows, cols = img.shape[:2]
M = np.float32([[1, 0, 50], [0, 1, 30]])
shifted = cv2.warpAffine(img, M, (cols, rows))

Алгоритмы фильтрации позволяют выделять важные особенности изображения или подавлять нежелательные шумы:

  1. Сглаживание (размытие):
Python
Скопировать код
# Размытие по Гауссу
blurred = cv2.GaussianBlur(img, (5, 5), 0)
# Медианный фильтр (хорош для удаления "соли и перца" шума)
median = cv2.medianBlur(img, 5)
# Двустороннее фильтрование (сохраняет края при сглаживании)
bilateral = cv2.bilateralFilter(img, 9, 75, 75)

  1. Обнаружение краёв:
Python
Скопировать код
# Фильтр Собеля (градиентные методы)
sobelx = cv2.Sobel(gray, cv2.CV_64F, 1, 0, ksize=5)
sobely = cv2.Sobel(gray, cv2.CV_64F, 0, 1, ksize=5)
# Детектор Кэнни (популярный алгоритм обнаружения краёв)
edges = cv2.Canny(gray, 100, 200)

  1. Морфологические операции:
Python
Скопировать код
# Создание ядра
kernel = np.ones((5, 5), np.uint8)
# Эрозия (уменьшение белых областей)
erosion = cv2.erode(binary_img, kernel, iterations=1)
# Дилатация (расширение белых областей)
dilation = cv2.dilate(binary_img, kernel, iterations=1)
# Открытие (эрозия, затем дилатация)
opening = cv2.morphologyEx(binary_img, cv2.MORPH_OPEN, kernel)
# Закрытие (дилатация, затем эрозия)
closing = cv2.morphologyEx(binary_img, cv2.MORPH_CLOSE, kernel)

Улучшение контраста и яркости — ещё один важный аспект обработки изображений:

Python
Скопировать код
# Эквализация гистограммы (улучшение контраста)
equalized = cv2.equalizeHist(gray)

# Адаптивная эквализация гистограммы (CLAHE)
clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8, 8))
clahe_result = clahe.apply(gray)

Пороговая обработка позволяет сегментировать изображение по яркости:

Python
Скопировать код
# Глобальное пороговое значение
ret, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)

# Адаптивное пороговое значение
adaptive_thresh = cv2.adaptiveThreshold(
gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C,
cv2.THRESH_BINARY, 11, 2)

# Метод Оцу (автоматически находит оптимальный порог)
ret, otsu = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)

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

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

Ключевой проблемой была нестабильность освещения при получении снимков. Решение пришло в виде комбинации морфологических операций и адаптивной пороговой обработки. После трех недель экспериментов мы смогли увеличить точность автоматического обнаружения патологий на 43%, что сократило время анализа одного пациента с 15 минут до 40 секунд. Это прекрасный пример того, как алгоритмы фильтрации в OpenCV могут буквально спасать жизни.

Распознавание объектов и лиц с помощью библиотеки cv2

Одна из самых впечатляющих возможностей библиотеки OpenCV — распознавание объектов и лиц. Это позволяет компьютеру автоматически находить и идентифицировать объекты на изображениях и в видеопотоке. 🔍

Рассмотрим основные методы распознавания, доступные в opencv-python документация:

Каскадные классификаторы Хаара

Это один из первых, но до сих пор эффективных методов для обнаружения объектов, особенно лиц:

Python
Скопировать код
import cv2

# Загрузка предварительно обученного классификатора
face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_frontalface_default.xml')
eye_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_eye.xml')

# Загрузка изображения
img = cv2.imread('face.jpg')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

# Обнаружение лиц
faces = face_cascade.detectMultiScale(gray, 1.3, 5)

# Для каждого обнаруженного лица
for (x, y, w, h) in faces:
# Рисуем прямоугольник вокруг лица
cv2.rectangle(img, (x, y), (x+w, y+h), (255, 0, 0), 2)

# Выделяем область интереса (лицо)
roi_gray = gray[y:y+h, x:x+w]
roi_color = img[y:y+h, x:x+w]

# Ищем глаза на лице
eyes = eye_cascade.detectMultiScale(roi_gray)
for (ex, ey, ew, eh) in eyes:
cv2.rectangle(roi_color, (ex, ey), (ex+ew, ey+eh), (0, 255, 0), 2)

cv2.imshow('Face Detection', img)
cv2.waitKey(0)
cv2.destroyAllWindows()

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

Обнаружение с помощью HOG (Гистограммы ориентированных градиентов)

HOG — это дескриптор признаков, который особенно эффективен для обнаружения людей:

Python
Скопировать код
import cv2

# Создание и настройка HOG-детектора людей
hog = cv2.HOGDescriptor()
hog.setSVMDetector(cv2.HOGDescriptor_getDefaultPeopleDetector())

# Загрузка изображения
img = cv2.imread('people.jpg')

# Обнаружение людей
boxes, weights = hog.detectMultiScale(img, winStride=(8, 8), padding=(4, 4), scale=1.05)

# Рисование прямоугольников вокруг обнаруженных людей
for (x, y, w, h) in boxes:
cv2.rectangle(img, (x, y), (x+w, y+h), (0, 0, 255), 2)

cv2.imshow('People Detection', img)
cv2.waitKey(0)
cv2.destroyAllWindows()

Обнаружение особых точек и сопоставление

Для распознавания конкретных объектов часто используют методы, основанные на особых точках (ключевых точках):

Python
Скопировать код
import cv2

# Загрузка изображений
img1 = cv2.imread('object.jpg', cv2.IMREAD_GRAYSCALE)
img2 = cv2.imread('scene.jpg', cv2.IMREAD_GRAYSCALE)

# Инициализация SIFT-детектора
sift = cv2.SIFT_create()

# Поиск ключевых точек и дескрипторов
kp1, des1 = sift.detectAndCompute(img1, None)
kp2, des2 = sift.detectAndCompute(img2, None)

# Сопоставление дескрипторов с помощью FLANN
FLANN_INDEX_KDTREE = 1
index_params = dict(algorithm=FLANN_INDEX_KDTREE, trees=5)
search_params = dict(checks=50)
flann = cv2.FlannBasedMatcher(index_params, search_params)
matches = flann.knnMatch(des1, des2, k=2)

# Выбор хороших совпадений по критерию Лоу
good_matches = []
for m, n in matches:
if m.distance < 0.7 * n.distance:
good_matches.append(m)

# Рисование совпадений
result = cv2.drawMatches(img1, kp1, img2, kp2, good_matches, None)

cv2.imshow('Object Recognition', result)
cv2.waitKey(0)
cv2.destroyAllWindows()

Использование глубокого обучения с OpenCV

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

Python
Скопировать код
import cv2
import numpy as np

# Загрузка модели
net = cv2.dnn.readNetFromCaffe('deploy.prototxt', 'model.caffemodel')

# Загрузка изображения
img = cv2.imread('image.jpg')
height, width = img.shape[:2]

# Подготовка входных данных для нейросети
blob = cv2.dnn.blobFromImage(cv2.resize(img, (300, 300)), 1.0,
(300, 300), (104.0, 177.0, 123.0))

# Передача входных данных через сеть
net.setInput(blob)
detections = net.forward()

# Обработка результатов
for i in range(detections.shape[2]):
confidence = detections[0, 0, i, 2]

# Фильтрация слабых обнаружений
if confidence > 0.5:
# Получение координат обнаруженного объекта
box = detections[0, 0, i, 3:7] * np.array([width, height, width, height])
(startX, startY, endX, endY) = box.astype("int")

# Рисование прямоугольника и метки
cv2.rectangle(img, (startX, startY), (endX, endY), (0, 255, 0), 2)
text = "{:.2f}%".format(confidence * 100)
cv2.putText(img, text, (startX, startY – 10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 2)

cv2.imshow("Deep Learning Detection", img)
cv2.waitKey(0)
cv2.destroyAllWindows()

Распознавание лиц

OpenCV также поддерживает алгоритмы распознавания (идентификации) лиц, а не только их обнаружения:

Python
Скопировать код
import cv2
import numpy as np
import os

# Создание распознавателя лиц
recognizer = cv2.face.LBPHFaceRecognizer_create()

# Загрузка обученной модели
recognizer.read('trainer.yml')

# Загрузка каскадного классификатора
faceCascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_frontalface_default.xml')

# Имена для идентифицированных лиц
names = ['Person1', 'Person2', 'Person3']

# Загрузка изображения
img = cv2.imread('test.jpg')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

# Обнаружение лиц
faces = faceCascade.detectMultiScale(gray, 1.3, 5)

# Для каждого обнаруженного лица
for (x, y, w, h) in faces:
# Выделение области интереса
roi_gray = gray[y:y+h, x:x+w]

# Распознавание
id, confidence = recognizer.predict(roi_gray)

# Если уверенность высокая
if confidence < 100:
id_name = names[id]
confidence_text = " {0}%".format(round(100 – confidence))
else:
id_name = "unknown"
confidence_text = " {0}%".format(round(100 – confidence))

# Рисование прямоугольника и метки
cv2.rectangle(img, (x, y), (x+w, y+h), (0, 255, 0), 2)
cv2.putText(img, id_name, (x+5, y-5), cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 255, 255), 2)
cv2.putText(img, confidence_text, (x+5, y+h-5), cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 255, 0), 1) 

cv2.imshow('Face Recognition', img)
cv2.waitKey(0)
cv2.destroyAllWindows()

Основные алгоритмы распознавания объектов в OpenCV:

  • Каскадные классификаторы Хаара — быстрые, но менее точные
  • HOG + SVM — эффективны для обнаружения людей
  • SIFT, SURF (патентованные), ORB (свободный) — для обнаружения по ключевым точкам
  • Методы глубокого обучения — наиболее точные, но требуют больше вычислительных ресурсов

Практические проекты компьютерного зрения на Python+OpenCV

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

Проект 1: Система видеонаблюдения с обнаружением движения

Создадим простую, но эффективную систему видеонаблюдения, которая обнаруживает движение и сохраняет соответствующие кадры:

Python
Скопировать код
import cv2
import datetime
import time

cap = cv2.VideoCapture(0) # Подключение к камере
time.sleep(2) # Даем камере время на инициализацию

# Получаем первый кадр для сравнения
_, first_frame = cap.read()
first_gray = cv2.cvtColor(first_frame, cv2.COLOR_BGR2GRAY)
first_gray = cv2.GaussianBlur(first_gray, (21, 21), 0)

while True:
# Получаем текущий кадр
_, frame = cap.read()
gray_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
gray_frame = cv2.GaussianBlur(gray_frame, (21, 21), 0)

# Вычисляем разницу между текущим и первым кадром
frame_delta = cv2.absdiff(first_gray, gray_frame)
thresh = cv2.threshold(frame_delta, 25, 255, cv2.THRESH_BINARY)[1]

# Увеличиваем белые области и находим контуры
thresh = cv2.dilate(thresh, None, iterations=2)
contours, _ = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

motion_detected = False
# Обрабатываем каждый контур
for contour in contours:
if cv2.contourArea(contour) < 1000: # Игнорируем маленькие контуры
continue

motion_detected = True
(x, y, w, h) = cv2.boundingRect(contour)
cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2)

# Если обнаружено движение, сохраняем кадр
if motion_detected:
timestamp = datetime.datetime.now().strftime("%Y-%m-%d_%H-%M-%S")
cv2.imwrite(f"motion_{timestamp}.jpg", frame)

# Добавляем информацию о времени на кадр
cv2.putText(frame, datetime.datetime.now().strftime("%A %d %B %Y %I:%M:%S%p"),
(10, frame.shape[0] – 10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 1)

# Отображаем результаты
cv2.imshow("Security Feed", frame)
cv2.imshow("Thresh", thresh)
cv2.imshow("Frame Delta", frame_delta)

# Обновляем первый кадр каждые 30 секунд для адаптации к изменениям освещения
if int(time.time()) % 30 == 0:
first_gray = gray_frame

# Выход при нажатии клавиши 'q'
key = cv2.waitKey(1) & 0xFF
if key == ord("q"):
break

cap.release()
cv2.destroyAllWindows()

Проект 2: Распознавание номерных знаков автомобилей

Автоматическое распознавание номерных знаков (ANPR) — популярное применение компьютерного зрения:

Python
Скопировать код
import cv2
import numpy as np
import pytesseract # Для OCR

# Путь к исполняемому файлу Tesseract (только для Windows)
pytesseract.pytesseract.tesseract_cmd = r'C:\Program Files\Tesseract-OCR\tesseract.exe'

# Загрузка изображения
img = cv2.imread('car.jpg')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

# Применение фильтра Собеля для обнаружения краев
sobel_x = cv2.Sobel(gray, cv2.CV_8U, 1, 0, ksize=3)

# Бинаризация
_, thresh = cv2.threshold(sobel_x, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)

# Морфологическое закрытие для соединения символов
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (17, 3))
closed = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel)

# Поиск контуров
contours, _ = cv2.findContours(closed, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
candidates = []

for contour in contours:
# Получение прямоугольной области
x, y, w, h = cv2.boundingRect(contour)
aspect_ratio = w / float(h)

# Фильтрация контуров по размеру и соотношению сторон (типичному для номерных знаков)
if 2.5 < aspect_ratio < 6.0 and w > 100 and h > 20:
candidates.append((x, y, w, h))

# Если найдены кандидаты, берем наибольший
if candidates:
x, y, w, h = max(candidates, key=lambda item: item[2] * item[3]) # Площадь = w * h
plate = img[y:y+h, x:x+w]

# Препроцессинг для улучшения OCR
plate_gray = cv2.cvtColor(plate, cv2.COLOR_BGR2GRAY)
_, plate_thresh = cv2.threshold(plate_gray, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)

# OCR на вырезанном номере
text = pytesseract.image_to_string(plate_thresh, config='-c tessedit_char_whitelist=0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ --psm 8')

# Отображение результата
cv2.rectangle(img, (x, y), (x+w, y+h), (0, 255, 0), 2)
cv2.putText(img, text.strip(), (x, y-10), cv2.FONT_HERSHEY_SIMPLEX, 0.9, (0, 255, 0), 2)

cv2.imshow("Plate", plate_thresh)

cv2.imshow("Result", img)
cv2.waitKey(0)
cv2.destroyAllWindows()

Проект 3: Подсчёт людей на видео

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

Python
Скопировать код
import cv2
import numpy as np

# Загрузка видео
cap = cv2.VideoCapture('people.mp4')

# Линия подсчёта (вертикальная линия посередине кадра)
line_position = None
count_up = 0
count_down = 0

# Для отслеживания объектов
object_detector = cv2.createBackgroundSubtractorMOG2(history=100, varThreshold=40)
trackers = []
next_id = 0

# Класс для отслеживания объектов
class Tracker:
def __init__(self, id, x, y, w, h):
self.id = id
self.x = x
self.y = y
self.w = w
self.h = h
self.center_points = [(x + w//2, y + h//2)] # История центральных точек
self.counted = False # Флаг, был ли объект уже посчитан
self.disappeared = 0 # Количество кадров, в течение которых объект не был найден

while True:
ret, frame = cap.read()
if not ret:
break

# Устанавливаем линию подсчёта, если ещё не установлена
if line_position is None:
line_position = frame.shape[1] // 2

# Рисуем линию подсчёта
cv2.line(frame, (line_position, 0), (line_position, frame.shape[0]), (0, 255, 0), 2)

# Применяем вычитание фона
mask = object_detector.apply(frame)
_, mask = cv2.threshold(mask, 254, 255, cv2.THRESH_BINARY)

# Морфологические операции для улучшения маски
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5))
mask = cv2.morphologyEx(mask, cv2.MORPH_OPEN, kernel)
mask = cv2.morphologyEx(mask, cv2.MORPH_CLOSE, kernel)

# Находим контуры
contours, _ = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

# Список текущих объектов
current_objects = []

for contour in contours:
# Фильтруем маленькие контуры
if cv2.contourArea(contour) < 1000:
continue

# Получаем ограничивающий прямоугольник
x, y, w, h = cv2.boundingRect(contour)
current_objects.append((x, y, w, h))

# Обновляем трекеры
for tracker in trackers:
tracker.disappeared += 1

# Для каждого текущего объекта
for obj in current_objects:
x, y, w, h = obj
center_point = (x + w//2, y + h//2)

# Проверяем, соответствует ли объект существующему трекеру
matched = False
for tracker in trackers:
if tracker.disappeared <= 10: # Проверяем только активные трекеры
# Если центр объекта близок к последнему центру трекера
last_center = tracker.center_points[-1]
distance = np.sqrt((center_point[0] – last_center[0])**2 + (center_point[1] – last_center[1])**2)

if distance < 50: # Порог расстояния
# Обновляем трекер
tracker.x, tracker.y, tracker.w, tracker.h = x, y, w, h
tracker.center_points.append(center_point)
tracker.disappeared = 0
matched = True
break

# Если не соответствует ни одному трекеру, создаём новый
if not matched:
new_tracker = Tracker(next_id, x, y, w, h)
next_id += 1
trackers.append(new_tracker)

# Отрисовываем трекеры и проверяем пересечение линии
for tracker in list(trackers):
# Удаляем трекеры, которые исчезли на долгое время
if tracker.disappeared > 20:
trackers.remove(tracker)
continue

# Отображаем только активные трекеры
if tracker.disappeared <= 10:
x, y, w, h = tracker.x, tracker.y, tracker.w, tracker.h
cv2.rectangle(frame, (x, y), (x+w, y+h), (0, 0, 255), 2)
cv2.putText(frame, str(tracker.id), (x, y-10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 2)

# Проверяем пересечение линии
if len(tracker.center_points) >= 2:
prev_center = tracker.center_points[-2]
curr_center = tracker.center_points[-1]

# Если объект пересек линию и еще не был посчитан
if not tracker.counted:
if (prev_center[0] < line_position and curr_center[0] >= line_position):
count_up += 1
tracker.counted = True
elif (prev_center[0] > line_position and curr_center[0] <= line_position):
count_down += 1
tracker.counted = True

# Отображаем счётчики
cv2.putText(frame, f"Up: {count_up}", (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 2)
cv2.putText(frame, f"Down: {count_down}", (10, 70), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 2)

cv2.imshow("Frame", frame)
cv2.imshow("Mask", mask)

key = cv2.waitKey(30)
if key == 27: # Esc
break

cap.release()
cv2.destroyAllWindows()

Вот еще несколько идей проектов для дальнейшего изучения:

  • Умное зеркало — распознавание лица и отображение персонализированной информации
  • Система управления жестами — контроль компьютера или устройства с помощью жестов рук
  • Аугментированная реальность — наложение виртуальных объектов на реальный мир
  • Анализ эмоций — определение эмоционального состояния людей по выражению лица
  • Классификация растений — определение видов растений по фотографиям листьев или цветов

Для каждого из этих проектов OpenCV предоставляет необходимые инструменты и функции, а Python делает их реализацию доступной даже для начинающих разработчиков.

Освоив OpenCV и Python, вы открываете для себя целый мир возможностей в области компьютерного зрения. От простых трансформаций изображений до сложных систем распознавания — все это теперь в ваших руках. Помните, что лучший способ изучения — это практика: начните с малого, экспериментируйте с разными алгоритмами и постепенно усложняйте свои проекты. Компьютерное зрение меняет отрасли от медицины до беспилотных автомобилей, и ваш следующий проект может стать частью этой революции. Делитесь своими решениями, учитесь у сообщества и не бойтесь ошибаться — каждая ошибка приближает вас к мастерству.

Читайте также

Проверь как ты усвоил материалы статьи
Пройди тест и узнай насколько ты лучше других читателей
Как установить библиотеку OpenCV в Python?
1 / 5

Загрузка...