OpenCV и Python: создание приложений компьютерного зрения с нуля
Для кого эта статья:
- Разработчики и программисты, интересующиеся компьютерным зрением
- Студенты и начинающие специалисты в области 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:
pip install opencv-python
Для дополнительных модулей, включающих патентованные алгоритмы и нестандартные функции:
pip install opencv-contrib-python
После установки можно импортировать библиотеку в Python-скрипт:
import cv2
Проверить установленную версию можно с помощью:
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 включает несколько этапов:
- Загрузка или захват изображения/видео
- Предобработка (изменение размера, фильтрация и т.д.)
- Применение алгоритмов компьютерного зрения
- Отображение или сохранение результатов
- Освобождение ресурсов
Александр Петров, инженер компьютерного зрения Мой путь в мир компьютерного зрения начался с банального вопроса: "Как автоматизировать сортировку фотографий по содержимому?" В поисках решения я наткнулся на OpenCV и Python. Начинал я с нуля — даже не знал, что такое open cv. Установка библиотеки казалась сложной, и первые две попытки завершились ошибками. Оказалось, что на Windows нужно было установить правильную версию Visual C++ и решить конфликты зависимостей.
Когда я наконец запустил свой первый скрипт, открывающий изображение, это было как первый шаг на Луну. Через месяц экспериментов я создал простую программу, распознающую лица на фотографиях и автоматически сортирующую их по папкам. Сейчас эта система обрабатывает тысячи изображений в нашем архиве, а начиналось всё с простой команды
pip install opencv-python.

Базовые операции с изображениями через OpenCV-Python
Начнем с базовых операций, которые составляют фундамент любой работы с изображениями в OpenCV. Первая задача — загрузка, отображение и сохранение изображений.
Для загрузки изображения используется функция python cv2 imread:
import cv2
# Загрузка изображения
img = cv2.imread('image.jpg')
По умолчанию изображение загружается в цветовом пространстве BGR. Если нужно загрузить его в оттенках серого, используем флаг:
img_gray = cv2.imread('image.jpg', cv2.IMREAD_GRAYSCALE)
Для отображения изображения используем функцию:
cv2.imshow('Image', img)
cv2.waitKey(0) # Ожидание нажатия клавиши
cv2.destroyAllWindows() # Закрытие всех окон
Сохранение обработанного изображения выполняется с помощью cv2 imwrite:
cv2.imwrite('processed_image.jpg', img)
Теперь рассмотрим основные операции с изображениями:
- Изменение размера:
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))
- Обрезка изображения:
# Вырезание региона [y:y+h, x:x+w]
cropped_img = img[100:300, 200:400]
- Конвертация цветовых пространств:
# 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)
- Рисование на изображениях:
# Рисование прямоугольника
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-массив, что позволяет легко манипулировать отдельными пикселями:
# Получение значения пикселя (для BGR изображения)
px = img[100, 100]
# Изменение значения пикселя
img[100, 100] = [255, 0, 0] # Устанавливаем синий цвет
Доступ к свойствам изображения:
# Получение размеров изображения
height, width, channels = img.shape
# Для изображения в оттенках серого
height, width = gray_img.shape
| Операция | Функция OpenCV | Сложность | Типичное применение |
|---|---|---|---|
| Загрузка изображения | cv2.imread() | Низкая | Начало любой обработки |
| Отображение | cv2.imshow() | Низкая | Визуализация результатов |
| Изменение размера | cv2.resize() | Низкая | Подготовка для нейросетей |
| Поворот | cv2.rotate() | Средняя | Коррекция ориентации |
| Изменение цветового пространства | cv2.cvtColor() | Низкая | Подготовка к обработке |
Также стоит упомянуть о работе с видео и веб-камерой:
# Чтение видео из файла
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 документация.
Начнём с базовых геометрических преобразований:
- Вращение:
# Вращение изображения на 45 градусов
rows, cols = img.shape[:2]
M = cv2.getRotationMatrix2D((cols/2, rows/2), 45, 1)
rotated = cv2.warpAffine(img, M, (cols, rows))
- Перспективные преобразования:
# Исходные точки
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))
- Аффинные преобразования:
# Смещение, масштабирование, вращение
rows, cols = img.shape[:2]
M = np.float32([[1, 0, 50], [0, 1, 30]])
shifted = cv2.warpAffine(img, M, (cols, rows))
Алгоритмы фильтрации позволяют выделять важные особенности изображения или подавлять нежелательные шумы:
- Сглаживание (размытие):
# Размытие по Гауссу
blurred = cv2.GaussianBlur(img, (5, 5), 0)
# Медианный фильтр (хорош для удаления "соли и перца" шума)
median = cv2.medianBlur(img, 5)
# Двустороннее фильтрование (сохраняет края при сглаживании)
bilateral = cv2.bilateralFilter(img, 9, 75, 75)
- Обнаружение краёв:
# Фильтр Собеля (градиентные методы)
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)
- Морфологические операции:
# Создание ядра
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)
Улучшение контраста и яркости — ещё один важный аспект обработки изображений:
# Эквализация гистограммы (улучшение контраста)
equalized = cv2.equalizeHist(gray)
# Адаптивная эквализация гистограммы (CLAHE)
clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8, 8))
clahe_result = clahe.apply(gray)
Пороговая обработка позволяет сегментировать изображение по яркости:
# Глобальное пороговое значение
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 документация:
Каскадные классификаторы Хаара
Это один из первых, но до сих пор эффективных методов для обнаружения объектов, особенно лиц:
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 — это дескриптор признаков, который особенно эффективен для обнаружения людей:
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()
Обнаружение особых точек и сопоставление
Для распознавания конкретных объектов часто используют методы, основанные на особых точках (ключевых точках):
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 есть поддержка нейронных сетей, что позволяет использовать модели глубокого обучения для более точного распознавания:
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 также поддерживает алгоритмы распознавания (идентификации) лиц, а не только их обнаружения:
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: Система видеонаблюдения с обнаружением движения
Создадим простую, но эффективную систему видеонаблюдения, которая обнаруживает движение и сохраняет соответствующие кадры:
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) — популярное применение компьютерного зрения:
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: Подсчёт людей на видео
Система для подсчёта количества людей, проходящих через определённую зону, может быть полезна для анализа трафика в магазинах, общественных местах и т.д.:
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, вы открываете для себя целый мир возможностей в области компьютерного зрения. От простых трансформаций изображений до сложных систем распознавания — все это теперь в ваших руках. Помните, что лучший способ изучения — это практика: начните с малого, экспериментируйте с разными алгоритмами и постепенно усложняйте свои проекты. Компьютерное зрение меняет отрасли от медицины до беспилотных автомобилей, и ваш следующий проект может стать частью этой революции. Делитесь своими решениями, учитесь у сообщества и не бойтесь ошибаться — каждая ошибка приближает вас к мастерству.
Читайте также
- Обязанности и требования к Python-разработчикам: полное руководство
- Управление потоком в Python: операторы break, continue и await
- История Python: от рождественского проекта до языка будущего
- Онлайн-интерпретаторы Python: 7 лучших сервисов для разработки
- ChatGPT для Python-кода: превращаем сложные алгоритмы в чистый код
- Цикл for в Python: 5 приемов эффективной обработки данных
- Переменные в Python: управление выполнением кода для оптимизации
- Оператор match-case в Python 3.10: мощный инструмент структурирования
- Контекстные менеджеры в Python: элегантный способ управления ресурсами
- Python боты для начинающих: пошаговое создание и интеграция API