OpenCV Python
| Введение | |
| Цветной → ЧБ | |
| resize: Изменить размер | |
| roteate: Повернуть | |
| imwrite: Сохранить | |
| Содержимое изображения | |
| Изменить изображение | |
| Работа с видео | |
| Похожие статьи |
Введение
OpenCV был запущен в Intel в 1999 году Гари Брэдски, а первый релиз вышел в 2000 году. Вадим Писаревский присоединился к Гари Брэдски, чтобы управлять российской командой Intel по
программному обеспечению OpenCV (leadership).
В 2005 году OpenCV использовался в Stanley, автомобиле, который выиграл DARPA Grand Challenge 2005 года. Позже его активная разработка продолжилась при поддержке Willow Garage, где Гари Брэдски и Вадим Писаревский возглавляли проект. Сейчас OpenCV поддерживает множество алгоритмов, связанных с компьютерным зрением и машинным обучением, и расширяется с каждым днем.
В настоящее время OpenCV поддерживает широкий спектр языков программирования, таких как
C++
,
Python
,
Java
и т. д., и доступен на разных платформах, включая
Windows
,
Linux
, OS X, Android, iOS и т. д. Кроме того, интерфейсы на основе CUDA и OpenCL также находятся в стадии активной разработки для высокоскоростных операций GPU.
OpenCV-Python
OpenCV-Python — это API Python для OpenCV. Он сочетает в себе лучшие качества OpenCV C++ API и языка Python.
Python — это язык программирования общего назначения, созданный Гвидо ван Россумом, который стал очень популярным за короткое время, в основном из-за своей простоты и читабельности кода. Он позволяет программисту выражать свои идеи в меньшем количестве строк кода, не снижая читабельности.
По сравнению с другими языками, такими как C/C++, Python медленнее. Но еще одной важной особенностью Python является то, что его можно легко расширить с помощью C/C++. Эта особенность помогает нам писать вычислительно интенсивные коды на C/C++ и создавать для них оболочку Python, чтобы мы могли использовать эти оболочки в качестве модулей Python. Это дает нам два преимущества: во-первых, наш код такой же быстрый, как и исходный код C/C++ (так как это фактический код C++, работающий в фоновом режиме), и, во-вторых, его очень легко кодировать на Python. Вот как работает OpenCV-Python, это оболочка Python вокруг исходной реализации C++.
А поддержка Numpy упрощает задачу. Numpy — это высокооптимизированная библиотека для числовых операций. Она предоставляет синтаксис в стиле MATLAB. Все структуры массивов OpenCV преобразуются в массивы Numpy и обратно. Поэтому любые операции, которые вы можете выполнять в Numpy, вы можете комбинировать с OpenCV, что увеличивает количество оружия в вашем арсенале. Кроме того, с этим можно использовать несколько других библиотек, таких как SciPy, Matplotlib, которые поддерживают Numpy.
Поэтому OpenCV-Python — это подходящий инструмент для быстрого прототипирования задач компьютерного зрения.
Учебники OpenCV-Python
OpenCV представляет новый набор учебных пособий, которые проведут вас по различным функциям, доступным в OpenCV-Python. Руководство, выложенное на официальном сайте в основном ориентировано на версию OpenCV 3.x (хотя большинство учебных пособий также будут работать с OpenCV 2.x), на момент написания этой статьи стабильная версия это 4.11.0, версия 5.0.0 находится в разработке.
Перед началом работы требуются предварительные знания Python и Numpy, поскольку они не будут рассматриваться в этом руководстве. В частности, хорошие знания Numpy необходимы для написания оптимизированных кодов в OpenCV-Python.
Документация
4.11.0
,
4.11.0 group__imgcodecs__flags
readthedocs.io
Сайт Александра Мордвинцева
Превращение цветного изображения в чёрно-белое
Структура преокта
cv2 ├── assets │ └── logo.jpg └── cv2_demo.py
В качестве logo.jpg можете использовать любое изображение. Я скачал логотип сайта HeiHei.ru
import cv2 img = cv2.imread('assets/logo.jpg', 0) # 0 означает чёрно-белый режим. Это равносильно # img = cv2.imread('assets/logo.jpg', cv2.IMREAD_GRAYSCALE) # Режимы: # -1, cv2.IMREAD_COLOR : Loads a color image. Any transparency of image will be neglected # 0, cv2.IMREAD_GRAYSCALE : Loads image in grayscale mode # 1, cv2.IMREAD_UNCHANGED : Loads image as such including alpha channel cv2.imshow('Image', img) # 0 означает, что ничего не произойдёт пока не будет нажата какая-либо кнопка cv2.waitKey(0) # В конце закроем все открытые окна cv2.destroyAllWindows()
python -m cv2_demo.py
На экране появится чёрно-белая версия изображения. Я искусственно ограничиваю ширину этого изображения на сайте так, чтобы оно не вылезало за края.
Если выбрать не 0 а 1 или -1, изображения будут следующего оригинального вида:
img = cv2.imread('assets/logo.jpg', 1)
Я разницы не вижу, но не буду ничего утверждать.
resize: Изменить размер
import cv2 img = cv2.imread('assets/logo.jpg', 1) # Уменьшим примерно в пять раз img = cv2.resize(img, (384, 78)) cv2.imshow('Image', img) cv2.waitKey(0) cv2.destroyAllWindows()
Это изображение на самом деле в пять раз меньше оригинала. На сайте я также искусственно ограничиваю ширину одной пятой экрана, чтобы не нарушать пропорции.
Чтобы не вычислять нужное разрешение вручную, можно указать в каком соотношении нужно изменить размер.
import cv2 img = cv2.imread('assets/logo.jpg', 1) img = cv2.resize(img, (0, 0), fx=0.2, fy=0.2) cv2.imshow('Image', img) cv2.waitKey(0) cv2.destroyAllWindows()
rotate: Повернуть изображение
import cv2 img = cv2.imread('assets/logo.jpg', 1) img = cv2.resize(img, (0, 0), fx=0.2, fy=0.2) img = cv2.rotate(img, cv2.ROTATE_90_COUNTERCLOCKWISE) cv2.imshow('Image', img) cv2.waitKey(0) cv2.destroyAllWindows()
imwrite: Сохранить изображение
import cv2 img = cv2.imread('assets/logo.jpg', 1) img = cv2.resize(img, (0, 0), fx=0.2, fy=0.2) img = cv2.rotate(img, cv2.ROTATE_90_COUNTERCLOCKWISE) cv2.imwrite('assets/new_logo.jpg', img) cv2.imshow('Image', img) cv2.waitKey(0) cv2.destroyAllWindows()
cv2 ├── assets │ ├── new_logo.jpg │ └── logo.jpg └── cv2_demo.py
Содержимое изображения
import cv2 img = cv2.imread('assets/logo.jpg', 1) print(img)
[[[254 254 254] [254 254 254] [254 254 254] ... [254 254 254] [254 254 254] [255 255 255]] [[254 254 254] [254 254 254] [254 254 254] ... [254 254 254] [254 254 254] [255 255 255]] [[254 254 254] [254 254 254] [254 254 254] ... [254 254 254] [254 254 254] [255 255 255]] ... [[254 254 254] [254 254 254] [254 254 254] ... [254 254 254] [254 254 254] [255 255 255]] [[255 255 255] [255 255 255] [255 255 255] ... [255 255 255] [255 255 255] [255 255 255]] [[255 255 255] [255 255 255] [255 255 255] ... [255 255 255] [255 255 255] [255 255 255]]]
Это - numpy.ndarray
… print(img.shape)
(391, 1921, 3)
391 строка, 1921 столбцов и 3 канала.
Канал
- это независимый набор значений для каждого пикселя. Например в RGB мы можем сказать о наличии трёх каналов. Первый хранит значения - насколько каждый пиксель красный. Второй - насколько каждый пиксель зелёный. Третий - синий.
В OpenCV порядок следующий: синий, зелёный, красный. Это можно проверить самостоятельно:
Распечатаем изображение два на два пикселя, полностью красного цвета.
import cv2 img = cv2.imread('assets/2x2red.png', 1) print(img) print(img.shape)
[[[ 0 0 255] [ 0 0 255]] [[ 0 0 255] [ 0 0 255]]] (2, 2, 3)
Две строки, два столбца, три канала. Третий канал 255. Значит действительно третий - это красный.
Более наглядная расстановка пикслей
[ [[ 0 0 255] [ 0 0 255]] [[ 0 0 255] [ 0 0 255]] ]
Распечатаем изображение два на два пикселя, полностью зелёного цвета.
[[[ 0 255 0] [ 0 255 0]] [[ 0 255 0] [ 0 255 0]]] (2, 2, 3)
Второе значение 255, значит это действительно зелёный. Методом исключения - первый это синий.
Рассмотрим изображение десять на десять пикселей, составленная из синего, зелёного, красного и чёрного квадратов пять на пять пикселей.
И научимся извлекать часть изображения.
Получить значение для отдельного пикселя можно указав номер строки и столбца: img[0][0]
import cv2 img = cv2.imread('assets/multisquare10.png', 1) print(img[7][0]) print(img[7][4]) print(img[7][5]) print(img[7][9])
[ 0 0 255] [ 0 0 255] [0 0 0] [0 0 0]
Можно изучить содержимое определённой строки.
… print(img[5])
[[ 0 0 255] [ 0 0 255] [ 0 0 255] [ 0 0 255] [ 0 0 255] [ 0 0 0] [ 0 0 0] [ 0 0 0] [ 0 0 0] [ 0 0 0]]
Если изображение большое и, следовательно, строка очень длинная, на экран может быть выведен сокращённый вариант: три первых пикслея … три последних пикселя.
Например, для логотипа heihei.ru мы бы получили что-то подобное:
[[254 254 254] [254 254 254] [254 254 254] ... [254 254 254] [254 254 254] [255 255 255]]
Можно получить дипазон строк. Например строка 4 где синие пиксели сменяются зелёными и строка 5 где красные пиксели сменяются чёрными.
… print(img[4:6])
[[[255 0 0] [255 0 0] [255 0 0] [255 0 0] [255 0 0] [ 0 255 0] [ 0 255 0] [ 0 255 0] [ 0 255 0] [ 0 255 0]] [[ 0 0 255] [ 0 0 255] [ 0 0 255] [ 0 0 255] [ 0 0 255] [ 0 0 0] [ 0 0 0] [ 0 0 0] [ 0 0 0] [ 0 0 0]]]
Из строки можно вырезать нужный дипазон.
… print(img[5][3:7])
[[ 0 0 255] [ 0 0 255] [ 0 0 0] [ 0 0 0]]
Изменить изображение
Для лучшей наглядности увеличим наш квадрат до размера сто на сто пикселей.
Заменим каждый пиксель чёрного квадрата на случайный
import cv2 import random img = cv2.imread('assets/multisquare100.png', 1) def rndm_clr(): return random.randint(0, 255) for i in range(50, 100): for j in range(50, 100): img[i, j] = [rndm_clr(), rndm_clr(), rndm_clr()] cv2.imwrite('assets/repainted100.png', img)
Скопируем из центра большого квадрата область 20 на 20 пикселей и вставим копию в верхний левый угол.
import cv2 img = cv2.imread('assets/multisquare100.png', 1) crop = img[40:60, 40:60] img[0:20, 0:20] = crop cv2.imwrite('assets/replaced100.png', img)
Работа с видео
Пример скрипта, который выводит видео с вебкамеры.
import cv2 cap = cv2.VideoCapture(0) while True: ret, frame = cap.read() cv2.imshow('frame', frame) if cv2.waitKey(1) & 0xFF == ord('q'): break cap.release() cv2.destroyAllWindows()
Чёрный экран такого же размера.
import numpy as np import cv2 cap = cv2.VideoCapture(0) while True: ret, frame = cap.read() image = np.zeros(frame.shape) cv2.imshow('frame', image) if cv2.waitKey(1) & 0xFF == ord('q'): break cap.release() cv2.destroyAllWindows()
import cv2 cap = cv2.VideoCapture(0) while True: ret, frame = cap.read() width = int(cap.get(3)) height = int(cap.get(4)) image = frame smaller_frame = cv2.resize(frame, (0, 0), fx=0.5, fy=0.5) image[:height // 2, :width // 2] = smaller_frame image[height // 2:, :width // 2] = smaller_frame image[:height // 2, width // 2:] = smaller_frame image[height // 2:, :width // 2:] = smaller_frame cv2.imshow('frame', image) if cv2.waitKey(1) & 0xFF == ord('q'): break cap.release() cv2.destroyAllWindows()
import cv2 cap = cv2.VideoCapture(0) while True: ret, frame = cap.read() width = int(cap.get(3)) height = int(cap.get(4)) image = frame smaller_frame = cv2.resize(frame, (0, 0), fx=0.5, fy=0.5) image[:height // 2, :width // 2] = cv2.rotate(smaller_frame, cv2.ROTATE_90_COUNTERCLOCKWISE) image[height // 2:, :width // 2] = cv2.rotate(smaller_frame, cv2.ROTATE_90_CLOCKWISE) image[:height // 2, width // 2:] = cv2.rotate(smaller_frame, cv2.ROTATE_180) image[height // 2:, :width // 2:] = smaller_frame cv2.imshow('frame', image) if cv2.waitKey(1) & 0xFF == ord('q'): break cap.release() cv2.destroyAllWindows()
Traceback (most recent call last):
File "C:\AutoTest\demo.py", line 14, in
Автор статьи: Андрей Олегович
| Установка OpenCV | |
| OCR | |
| pytesseract | |
| Python |