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

Логотип сайта 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

На экране появится чёрно-белая версия изображения. Я искусственно ограничиваю ширину этого изображения на сайте так, чтобы оно не вылезало за края.

Чёрно-белый логотип сайта HeiHei.ru

Если выбрать не 0 а 1 или -1, изображения будут следующего оригинального вида:

img = cv2.imread('assets/logo.jpg', 1)

Цветной логотип сайта HeiHei.ru Цветной логотип сайта HeiHei.ru

Я разницы не вижу, но не буду ничего утверждать.

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()

Цветной логотип сайта HeiHei.ru

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

Чтобы не вычислять нужное разрешение вручную, можно указать в каком соотношении нужно изменить размер.

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()

Цветной логотип сайта HeiHei.ru

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()

Цветной логотип сайта HeiHei.ru

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 порядок следующий: синий, зелёный, красный. Это можно проверить самостоятельно:

Распечатаем изображение два на два пикселя, полностью красного цвета.

Красный квадрат два на два пикселя изображение с сайта https://www.devhops.ru

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]] ]

Распечатаем изображение два на два пикселя, полностью зелёного цвета.

Красный квадрат два на два пикселя изображение с сайта https://www.devhops.ru

[[[ 0 255 0] [ 0 255 0]] [[ 0 255 0] [ 0 255 0]]] (2, 2, 3)

Второе значение 255, значит это действительно зелёный. Методом исключения - первый это синий.

Рассмотрим изображение десять на десять пикселей, составленная из синего, зелёного, красного и чёрного квадратов пять на пять пикселей.

Разноцветный квадрат десять на десять пикселей изображение с сайта https://www.devhops.ru

И научимся извлекать часть изображения.

Получить значение для отдельного пикселя можно указав номер строки и столбца: 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]]

Изменить изображение

Для лучшей наглядности увеличим наш квадрат до размера сто на сто пикселей.

Разноцветный квадрат десять на десять пикселей изображение с сайта https://www.devhops.ru

Заменим каждый пиксель чёрного квадрата на случайный

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)

Разноцветный квадрат десять на десять пикселей изображение с сайта https://www.devhops.ru

Скопируем из центра большого квадрата область 20 на 20 пикселей и вставим копию в верхний левый угол.

Разноцветный квадрат десять на десять пикселей изображение с сайта https://www.devhops.ru

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)

Разноцветный квадрат десять на десять пикселей изображение с сайта https://www.devhops.ru

Работа с видео

Пример скрипта, который выводит видео с вебкамеры.

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()

Чёрный экран вебкамеры изображение с сайта https://www.devhops.ru

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 image[:height // 2, :width // 2] = cv2.rotate(smaller_frame, cv2.ROTATE_90_COUNTERCLOCKWISE) ~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^ ValueError: could not broadcast input array from shape (320,240,3) into shape (240,320,3)

Автор статьи: Андрей Олегович

Похожие статьи
Установка OpenCV
OCR
pytesseract
Python

РЕКЛАМА хостинга Beget, которым я пользуюсь более десяти лет

Изображение баннера

Конец рекламы хостинга Beget, который я всем рекомендую.

Поиск по сайту

Подпишитесь на Telegram канал @aofeed чтобы следить за выходом новых статей и обновлением старых

Перейти на канал

@aofeed

Задать вопрос в Телеграм-группе

@aofeedchat

Контакты и сотрудничество:
Рекомендую наш хостинг beget.ru
Пишите на info@urn.su если Вы:
1. Хотите написать статью для нашего сайта или перевести статью на свой родной язык.
2. Хотите разместить на сайте рекламу, подходящую по тематике.
3. Реклама на моём сайте имеет максимальный уровень цензуры. Если Вы увидели рекламный блок недопустимый для просмотра детьми школьного возраста, вызывающий шок или вводящий в заблуждение - пожалуйста свяжитесь с нами по электронной почте
4. Нашли на сайте ошибку, неточности, баг и т.д. ... .......
5. Статьи можно расшарить в соцсетях, нажав на иконку сети: