Библиотека OpenCV (cv2) в Python: от основ до сложных методов

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

Основные операции с изображениями

Библиотека OpenCV (cv2) предоставляет обширный набор функций для работы с изображениями и видео. Далее рассмотрены базовые и альтернативные подходы.

Как загрузить изображение, отобразить его и сохранить?


import cv2
img = cv2.imread('image.jpg')
cv2.imshow('Image', img)
cv2.waitKey(0)
cv2.destroyAllWindows()
cv2.imwrite('output.jpg', img)
  

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

Пояснение: Функция cv2.imread() загружает изображение из файла. Если файл не найден, возвращается None. cv2.imshow() открывает окно с указанным именем. cv2.waitKey(0) ожидает нажатия клавиши. cv2.imwrite() сохраняет изображение в указанный формат.

Типичные ошибки:
  • Ошибка пути к файлу - img будет None. Всегда проверять if img is None.
  • Окно не закрывается - забыт cv2.destroyAllWindows().
  • Изображение отображается в черно-белом режиме - возможно, файл является одноканальным.

Как изменить размер изображения, сохранив пропорции?


import cv2
img = cv2.imread('image.jpg')
h, w = img.shape[:2]
new_w = 300  # ширина
ratio = new_w / w
new_h = int(h * ratio)
resized = cv2.resize(img, (new_w, new_h), interpolation=cv2.INTER_AREA)
  

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

Пояснение: Для сохранения пропорций вычисляется отношение ширины. cv2.resize() с INTER_AREA подходит для уменьшения, INTER_LINEAR для увеличения. INTER_CUBIC даёт более гладкий результат при увеличениях.

Частые проблемы:
  • Ошибка приведения типа - new_h должен быть целым числом.
  • Искажение пропорций: если не вычислять ratio, изображение сжимается.

Как преобразовать цветовое пространство, например BGR в оттенки серого?


import cv2
img = cv2.imread('image.jpg')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
  

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

Пояснение: OpenCV по умолчанию использует порядок каналов BGR. Для получения серого используется COLOR_BGR2GRAY. Другие распространённые преобразования: COLOR_BGR2HSV, COLOR_BGR2RGB.

Типичная ошибка:
  • Путаница BGR и RGB. При отображении через matplotlib цвета будут искажены, если не конвертировать в RGB.

Как применить размытие для уменьшения шума?


import cv2
img = cv2.imread('image.jpg')
blur = cv2.GaussianBlur(img, (5,5), 0)
median = cv2.medianBlur(img, 5)
bilateral = cv2.bilateralFilter(img, 9, 75, 75)
  

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

Пояснение: GaussianBlur - линейное размытие. medianBlur эффективен против соли-перца. bilateralFilter сохраняет границы, размывая внутренние области. Размер ядра задаётся нечётным числом.

Проблемы:
  • Слишком большое ядро - потеря деталей.
  • Для bilateralFilter большие значения параметров замедляют обработку.

Как выполнить пороговое выделение объектов?


import cv2
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
ret, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)
adaptive = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 11, 2)
otsu = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)[1]
  

распознавание объектов python (распознавание объектов с помощью python)

Пояснение: Базовый порог cv2.threshold фиксирован. Адаптивный порог учитывает локальную освещённость. Метод Оцу автоматически выбирает оптимальный порог. Подходит для бимодальных гистограмм.

Ошибки:
  • При фиксированном пороге на неравномерном освещении результат плохой.
  • Оцу не работает, если гистограмма не бимодальна.

Как найти и отрисовать контуры на изображении?


import cv2
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
ret, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)
contours, _ = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
cv2.drawContours(img, contours, -1, (0,255,0), 2)
  

Пояснение: findContours возвращает список контуров и иерархию. Режим RETR_TREE - все контуры в иерархии. CHAIN_APPROX_SIMPLE сжимает горизонтальные и вертикальные линии. drawContours рисует на изображении.

Частые сложности:
  • На вход требуется бинарное изображение (чёрно-белое).
  • Контуры могут быть вложенными, необходимо правильно выбирать режим.

Как применить морфологические операции для очистки шума?


import cv2
import numpy as np
kernel = np.ones((5,5), np.uint8)
erosion = cv2.erode(thresh, kernel, iterations=1)
dilation = cv2.dilate(thresh, kernel, iterations=1)
opening = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel)
closing = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel)
  

Пояснение: Эрозия удаляет белые точки на чёрном фоне. Дилатация увеличивает белые области. Открытие (эрозия + дилатация) удаляет шум. Закрытие (дилатация + эрозия) заполняет дыры. Форма ядра может быть cv2.getStructuringElement().

Проблемы:
  • Слишком большая итерация - удаление нужных объектов.
  • Неподходящий размер ядра - эффект недостаточен или чрезмерен.

Продвинутые примеры использования OpenCV

Детекция лиц с помощью каскадов Хаара

Пример

import cv2
face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
img = cv2.imread('group.jpg')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
faces = face_cascade.detectMultiScale(gray, 1.1, 5)
for (x,y,w,h) in faces:
    cv2.rectangle(img, (x,y), (x+w,y+h), (0,255,0), 2)
cv2.imshow('Faces', img)
cv2.waitKey(0)
  
Результат: изображение с зелёными прямоугольниками, обозначающими найденные лица. При отсутствии каскадного файла возникает ошибка. Файл можно загрузить из репозитория OpenCV.

Панорамное склеивание нескольких изображений

Пример

import cv2
imgs = [cv2.imread('left.jpg'), cv2.imread('center.jpg'), cv2.imread('right.jpg')]
stitcher = cv2.Stitcher.create(cv2.Stitcher_PANORAMA)
status, pano = stitcher.stitch(imgs)
if status == cv2.Stitcher_OK:
    cv2.imwrite('panorama.jpg', pano)
else:
    print('Ошибка склеивания:', status)
  
Результат: одно объединённое изображение (панорама). Ошибки часто связаны с недостаточным перекрытием или плохим качеством совмещения.

Отслеживание объекта в видео с помощью трекера CSRT

Пример

import cv2
cap = cv2.VideoCapture('video.mp4')
ret, frame = cap.read()
bbox = cv2.selectROI('Object', frame, False)
tracker = cv2.TrackerCSRT_create()
tracker.init(frame, bbox)
while True:
    ret, frame = cap.read()
    if not ret: break
    ret, bbox = tracker.update(frame)
    if ret:
        x,y,w,h = [int(v) for v in bbox]
        cv2.rectangle(frame, (x,y), (x+w,y+h), (255,0,0), 2)
    cv2.imshow('Tracking', frame)
    if cv2.waitKey(30) == 27: break
cap.release()
cv2.destroyAllWindows()
  
Результат: видео с синим прямоугольником вокруг отслеживаемого объекта. Трекер может потерять цель при резком движении или перекрытии.

Сегментация изображений с помощью алгоритма водораздела (watershed)

Пример

import cv2
import numpy as np
img = cv2.imread('coins.jpg')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
ret, thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)
kernel = np.ones((3,3), np.uint8)
opening = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel, iterations=2)
sure_bg = cv2.dilate(opening, kernel, iterations=3)
dist = cv2.distanceTransform(opening, cv2.DIST_L2, 5)
ret, sure_fg = cv2.threshold(dist, 0.7*dist.max(), 255, 0)
sure_fg = np.uint8(sure_fg)
unknown = cv2.subtract(sure_bg, sure_fg)
ret, markers = cv2.connectedComponents(sure_fg)
markers = markers + 1
markers[unknown == 255] = 0
markers = cv2.watershed(img, markers)
img[markers == -1] = [0,0,255]
cv2.imshow('Segmented', img)
  
Результат: изображение монет, разделённых красными границами. Алгоритм чувствителен к настройкам порога и морфологии.

Библиотека OpenCV в Python - comments

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