Django-Admin.ru

OpenCV в Python: установка cv2 и первые шаги

Как установить OpenCV для Python (pip install opencv-python, а не cv2), прочитать, показать и сохранить изображение, работать с цветом, размером и камерой.

Редакция Django-Admin.ru
· обновлено · 10 мин чтения

Содержание · 12 разделов
  1. Как установить OpenCV для Python
  2. Какой пакет выбрать: opencv-python, contrib или headless
  3. Чтение изображения: cv2.imread
  4. Показ изображения: cv2.imshow
  5. Сохранение: cv2.imwrite
  6. BGR вместо RGB
  7. Оттенки серого и другие цветовые пространства
  8. Изменение размера, обрезка и поворот
  9. Рисование и текст
  10. Видео с веб-камеры
  11. Частые ошибки
  12. ModuleNotFoundError: No module named ‘cv2’
  13. cv2.imshow не работает: «The function is not implemented»
  14. Как показать изображение в Jupyter Notebook
  15. ImportError: libGL.so.1 на Linux или в Docker
  16. Ошибка (-215:Assertion failed) !_src.empty()
  17. imread возвращает None для пути с кириллицей
  18. Частые вопросы
  19. Почему в OpenCV 5 нет cv2.CascadeClassifier?
  20. Как поставить OpenCV 4 вместо 5?
  21. Что ещё изменилось в OpenCV 5 для кода на Python?
  22. Как перевести изображение из OpenCV в Pillow и обратно?
  23. Как сохранить обработанное видео в файл?
  24. Итог

OpenCV — библиотека компьютерного зрения: чтение и обработка изображений, видео с камеры, поиск контуров, фильтры и многое другое. В Python она импортируется как модуль cv2, но устанавливается под другим именем. Быстрый ответ на вопрос «pip install cv2»:

pip install opencv-python
import cv2

print(cv2.__version__)  # → 5.0.0 (или 4.x — зависит от установленной версии)

Команда pip install cv2 не сработает: пакета с таким именем в PyPI нет. Ниже — какой из пакетов OpenCV выбрать, первые операции с изображениями и разбор частых ошибок. Примеры проверены на OpenCV 5.0 и Python 3.12; все показанные функции есть и в OpenCV 4.x.

Как установить OpenCV для Python

Устанавливайте пакет в виртуальное окружение проекта тем же интерпретатором, которым будете запускать код:

# Windows
py -m pip install opencv-python

# macOS / Linux
python3 -m pip install opencv-python

Вместе с OpenCV установится NumPy — изображения в cv2 хранятся как массивы NumPy. Общие правила установки пакетов описаны в статьях про pip и установку библиотек Python.

Какой пакет выбрать: opencv-python, contrib или headless

Команда pip install cv2 завершается ошибкой:

ERROR: Could not find a version that satisfies the requirement cv2 (from versions: none)
ERROR: No matching distribution found for cv2

Официальные сборки OpenCV для Python публикуются в PyPI четырьмя пакетами. Все они дают один и тот же import cv2:

ПакетЧто внутриКогда выбирать
opencv-pythonосновные модули и окна (cv2.imshow)компьютер с рабочим столом
opencv-contrib-pythonто же + дополнительные модули из opencv_contribнужны модули, которых нет в основной сборке
opencv-python-headlessосновные модули без GUIсервер, Docker, CI, Jupyter
opencv-contrib-python-headlesscontrib без GUIcontrib на сервере

В OpenCV 5.0 часть классического функционала перенесли в contrib: каскады Хаара cv2.CascadeClassifier, детектор cv2.HOGDescriptor и модуль машинного обучения cv2.ml. В основной сборке 5.0 их нет — для старого кода с этими классами нужен contrib-пакет.

Важно: ставьте только один из этих пакетов. Они устанавливают файлы в одну и ту же папку cv2 и конфликтуют. Если вы меняете вариант, сначала удалите старый: pip uninstall opencv-python opencv-contrib-python opencv-python-headless.

Чтение изображения: cv2.imread

import cv2

img = cv2.imread("photo.jpg")
if img is None:
    raise FileNotFoundError("Не удалось прочитать photo.jpg")

print(type(img))   # → <class 'numpy.ndarray'>
print(img.shape)   # → (300, 400, 3) — высота, ширина, каналы
print(img.dtype)   # → uint8 — значения от 0 до 255
h, w = img.shape[:2]

cv2.imread() не выбрасывает исключение, если файла нет или он повреждён, — функция возвращает None и пишет предупреждение в консоль. Поэтому проверка на None обязательна, иначе ошибка всплывёт позже в непонятном месте.

Второй аргумент задаёт режим чтения: cv2.IMREAD_GRAYSCALE сразу загрузит картинку в оттенках серого, cv2.IMREAD_UNCHANGED сохранит альфа-канал PNG.

Показ изображения: cv2.imshow

cv2.imshow("Photo", img)
cv2.waitKey(0)           # ждать нажатия любой клавиши
cv2.destroyAllWindows()

Без cv2.waitKey() окно не успеет отрисоваться. Аргумент — время ожидания в миллисекундах, 0 — ждать бесконечно.

Окна работают только с пакетом opencv-python (или contrib) на компьютере с графическим окружением. В Jupyter, на сервере и с headless-сборкой используйте другие способы — они разобраны в разделе «Частые ошибки».

Сохранение: cv2.imwrite

cv2.imwrite("result.png", img)                                  # → True
cv2.imwrite("result.jpg", img, [cv2.IMWRITE_JPEG_QUALITY, 90])  # качество JPEG 0–100

Формат определяется по расширению файла. Функция возвращает True или False — исключений при неудаче тоже нет.

BGR вместо RGB

OpenCV хранит цветные пиксели в порядке BGR (синий, зелёный, красный), а не RGB, как Pillow, Matplotlib и большинство других библиотек. Это главный источник «синих лиц» на картинках новичков.

b, g, r = img[0, 0]       # пиксель в левом верхнем углу
rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)

Цвета в функциях рисования тоже задаются в BGR: (0, 0, 255) — красный, (255, 0, 0) — синий.

Оттенки серого и другие цветовые пространства

gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)   # (300, 400) — один канал
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)     # удобно для поиска объектов по цвету

Многие алгоритмы — пороговая обработка, поиск границ, контуры — работают с одноканальным изображением, поэтому перевод в серый часто идёт первым шагом:

blur = cv2.GaussianBlur(gray, (5, 5), 0)              # сгладить шум
edges = cv2.Canny(blur, 100, 200)                     # границы объектов
_, mask = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)

Изменение размера, обрезка и поворот

small = cv2.resize(img, (200, 150))   # (ширина, высота)!
half = cv2.resize(img, None, fx=0.5, fy=0.5, interpolation=cv2.INTER_AREA)

# Сохранить пропорции: ширина 800, высота по расчёту
new_w = 800
new_h = int(h * new_w / w)
big = cv2.resize(img, (new_w, new_h), interpolation=cv2.INTER_LINEAR)

Обратите внимание на порядок: img.shape возвращает (высота, ширина), а cv2.resize() принимает (ширина, высота). Для уменьшения рекомендуется интерполяция INTER_AREA, для увеличения — INTER_LINEAR или INTER_CUBIC.

Обрезка делается срезом массива NumPy — сначала строки (y), потом столбцы (x):

crop = img[50:150, 100:300]                      # y от 50 до 150, x от 100 до 300
flipped = cv2.flip(img, 1)                       # зеркально по горизонтали
rotated = cv2.rotate(img, cv2.ROTATE_90_CLOCKWISE)

Срез — это представление исходного массива, а не копия: изменения в crop отразятся на img. Если нужна независимая копия, вызовите crop.copy().

Рисование и текст

Функции рисования изменяют изображение на месте. Координаты — (x, y) от левого верхнего угла:

cv2.rectangle(img, (50, 50), (200, 150), (0, 255, 0), 2)   # зелёная рамка толщиной 2
cv2.circle(img, (300, 100), 40, (0, 0, 255), -1)            # красный круг, -1 = заливка
cv2.line(img, (0, 0), (399, 299), (255, 0, 0), 3)           # синяя линия
cv2.putText(img, "Hello, OpenCV", (20, 280),
            cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 255, 255), 2)
cv2.imwrite("result.png", img)

В OpenCV 4.x шрифты Hershey поддерживают только латиницу: кириллица в putText() превращается в вопросительные знаки, поэтому русские подписи там рисуют через Pillow (ImageDraw.text() с TTF-шрифтом). В OpenCV 5.0 текст рисует новый движок TrueType со встроенным шрифтом Rubik. Константы FONT_HERSHEY_* работают как раньше, но строки UTF-8, в том числе на русском, выводятся корректно; размер и начертание букв немного отличаются от 4.x. Для другого шрифта есть класс cv2.FontFace:

font = cv2.FontFace("sans")  # встроенный шрифт или путь к файлу .ttf
cv2.putText(img, "Привет, OpenCV", (20, 240), (255, 255, 255), font, 32)  # цвет, шрифт, размер

Видео с веб-камеры

import cv2

cap = cv2.VideoCapture(0)   # 0 — первая камера; вместо числа можно указать путь к видеофайлу
if not cap.isOpened():
    raise RuntimeError("Камера не найдена")

while True:
    ok, frame = cap.read()       # frame — обычное изображение BGR
    if not ok:
        break
    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
    cv2.imshow("Camera", gray)
    if cv2.waitKey(1) & 0xFF == ord("q"):   # выход по клавише q
        break

cap.release()
cv2.destroyAllWindows()

cap.read() возвращает пару: флаг успеха и кадр. В конце видеофайла или при отключении камеры флаг станет False — без проверки на следующей строке будет ошибка. cap.release() освобождает камеру для других программ.

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

ModuleNotFoundError: No module named ‘cv2’

Пакет не установлен или установлен в другой интерпретатор. Проверьте:

python -m pip show opencv-python opencv-python-headless
python -c "import sys; print(sys.executable)"

Установите OpenCV командой python -m pip install opencv-python тем же python, которым запускаете скрипт. В PyCharm и VS Code убедитесь, что выбран интерпретатор вашего venv. Общий разбор — в статье про ModuleNotFoundError.

cv2.imshow не работает: «The function is not implemented»

cv2.error: OpenCV(5.0.0) ... error: (-2:Unspecified error) The function is not implemented.
Rebuild the library with Windows, GTK+ 2.x or Cocoa support. ... in function 'showImageImpl'

Установлена headless-сборка — в ней нет окон. На рабочем компьютере замените её на opencv-python (удалите headless-пакет и поставьте обычный). На сервере окна не нужны: сохраняйте результат через cv2.imwrite().

Как показать изображение в Jupyter Notebook

cv2.imshow() в Jupyter открывает отдельное окно, которое может зависнуть вместе с ядром, а на удалённом сервере не работает вовсе. Показывайте картинку через Matplotlib, не забыв перевести BGR в RGB:

import matplotlib.pyplot as plt

plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
plt.axis("off")
plt.show()

ImportError: libGL.so.1 на Linux или в Docker

Обычный opencv-python требует системных графических библиотек, которых нет в минимальных образах. Установите вместо него opencv-python-headless — для серверной обработки окна не нужны.

Ошибка (-215:Assertion failed) !_src.empty()

Функция получила пустое изображение — почти всегда это None из cv2.imread() (неверный путь) или cap.read() (кадр не получен). Проверяйте результат сразу после чтения.

imread возвращает None для пути с кириллицей

На Windows cv2.imread() и cv2.imwrite() не работают с путями, где есть не-ASCII символы: чтение вернёт None, а запись может создать файл с искажённым именем. Обходной путь — читать и писать байты средствами NumPy:

import numpy as np

img = cv2.imdecode(np.fromfile("фото.jpg", dtype=np.uint8), cv2.IMREAD_COLOR)

ok, buffer = cv2.imencode(".jpg", img)
buffer.tofile("результат.jpg")

Частые вопросы

Почему в OpenCV 5 нет cv2.CascadeClassifier?

В OpenCV 5.0 каскады Хаара перенесли в contrib, поэтому в opencv-python код падает с AttributeError: module 'cv2' has no attribute 'CascadeClassifier'. Поставьте opencv-contrib-python вместо основного пакета. XML-файлы каскадов в сборки 5.0 не входят — папка cv2.data.haarcascades пуста, файл haarcascade_frontalface_default.xml нужно скачать из репозитория OpenCV. Для нового кода распознавания лиц лучше подходит нейросетевой детектор cv2.FaceDetectorYN из основной сборки с моделью YuNet в формате ONNX.

Как поставить OpenCV 4 вместо 5?

Ограничьте версию при установке:

pip install "opencv-python<5"

Это нужно для старого кода, который использует cv2.ml, загрузку моделей Caffe или Darknet через cv2.dnn и другие возможности, убранные из основной сборки 5.0. Версию в requirements.txt закрепляйте так же: opencv-python<5.

Что ещё изменилось в OpenCV 5 для кода на Python?

Импорт не изменился: функции перенесённых модулей по-прежнему вызываются как cv2.имя_функции(). Из заметных изменений: cv2.dnn больше не читает модели Caffe и Darknet (их конвертируют в ONNX), VideoCapture.get() возвращает -1 вместо 0 для неподдерживаемого свойства, а resize() с INTER_NEAREST даёт тот же результат, что Pillow. Полный список — в руководстве по переходу с OpenCV 4 на 5.

Как перевести изображение из OpenCV в Pillow и обратно?

Оба формата — это массив пикселей, отличается только порядок каналов:

import cv2
import numpy as np
from PIL import Image

pil_img = Image.fromarray(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))   # OpenCV → Pillow
img = cv2.cvtColor(np.array(pil_img), cv2.COLOR_RGB2BGR)          # Pillow → OpenCV

Как сохранить обработанное видео в файл?

Используйте cv2.VideoWriter: кодек, частота кадров и размер (ширина, высота) должны совпадать с кадрами, которые вы записываете.

cap = cv2.VideoCapture("input.mp4")
fps = cap.get(cv2.CAP_PROP_FPS)
w = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
h = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
out = cv2.VideoWriter("output.mp4", cv2.VideoWriter_fourcc(*"mp4v"), fps, (w, h))

while True:
    ok, frame = cap.read()
    if not ok:
        break
    out.write(cv2.flip(frame, 1))  # любая обработка кадра

cap.release()
out.release()

Если размер кадра не совпадает с указанным, файл получится пустым или не откроется.

Итог

Чтобы начать работу с OpenCV в Python, установите opencv-python (или headless-вариант для сервера), импортируйте cv2 и помните три правила: проверяйте результат imread() на None, учитывайте порядок каналов BGR и порядок (ширина, высота) в resize(). Полный справочник функций — в документации OpenCV. Другие библиотеки для изображений и данных — в обзоре библиотек Python; табличные данные удобно обрабатывать в pandas.

  • #Python
  • #OpenCV
  • #cv2
  • #Компьютерное зрение
  • #Изображения
↑ ↓ выборEnter открытьEsc закрыть