Библиотека 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)
Результат: изображение монет, разделённых красными границами. Алгоритм чувствителен к настройкам порога и морфологии.