В последней статье мы определили изображения, представили OpenCV и способы взаимодействия с изображениями с помощью OpenCV. В этой части мы продолжим наше путешествие по обработке изображений с использованием OpenCV с Python. В частности, мы поговорим о том, как получить доступ к свойствам изображения, вырезать часть изображения и разделить каналы изображения.
Все материалы этой серии доступны в этом репозитории Github.
1. Свойства изображения
Каждое изображение имеет ширину (количество пикселей в строке), высоту (количество пикселей в столбце) и количество каналов (двоичные изображения и изображения в оттенках серого имеют один канал, а цветные изображения — три канала).
Когда мы читаем изображение с помощью OpenCV, он возвращает массив Numpy, представляющий это изображение. Мы можем получить доступ к свойствам изображения, используя array.shape
. Этот метод возвращает кортеж Python (высота, ширина, каналы), к которому мы можем получить доступ для получения этих свойств. Обратите внимание, что первый элемент этого кортежа — это высота, а второй — ширина, которая отличается от обычных утилит, где ширина обычно задается как первый элемент. Кроме того, третий элемент (каналы) обычно опускается в случае двоичных изображений и изображений в оттенках серого, где он равен 1.
Теперь давайте сделаем это на практике, используя OpenCV с Python:
# First import OpenCV and Numpy import cv2 import numpy as np # Read the image image = cv2.imread("path/to/image") # Show the image type (It will be a Numpy array) print(type(image)) # Access the type of data in this array (It should be uint8) print(image.dtype) # Access width, height, and channels shape = image.shape height = shape[0] width = shape[1] channels = shape[2] # Not available if you read the image as grayscale print("Width": width, " Height:", height, " Channels: ", channels) # Access the number of pixels in the image print("Size: ", image.size)
Преобразование между BGR, оттенками серого и RBG
OpenCV по умолчанию считывает изображение как изображение BGR, поэтому первый канал будет представлять синий цвет, второй — зеленый, а третий — красный. Мы можем преобразовать это изображение в оттенки серого или RGB, если нам нужно использовать их в этих пространствах. Например, нам может понадобиться изображение в оттенках серого для выполнения некоторых конкретных методов обработки изображений или нам может понадобиться изображение для использования с другим инструментом (например, Matplotlib).
Мы можем конвертировать между этими пространствами, используя метод OpenCV под названием cvtColor()
, который принимает в качестве параметров: изображение в исходном пространстве и желаемое пространство. Давайте посмотрим это на практике:
# Import libraries and read image like in the code above image_bgr = cv2.imread("path/to/image") # Per default in BGR # Convert from BGR to RGB image_rgb = cv2.cvtColor(image_bgr, cv2.COLOR_BGR2RGB) # Convert from BGR to Grayscale image_gray = cv2.cvtColor(image_bgr, cv2.COLOR_BGR2GRAY)
Тот же принцип применим и к другим цветовым пространствам, например HSV.
2. Манипулирование изображениями
Доступ к пикселям и рентабельности инвестиций
Вы можете получить доступ к каждому пикселю изображения по его координатам. Например, если вы хотите получить доступ к пикселю в 100-й строке и 50-м столбце, вы можете использовать срез NumPy: image[50, 100]
. Если изображение является цветным, результатом будет кортеж из трех элементов, представляющих синий, зеленый и красный. Результатом будет скаляр, если изображение представляет собой полутоновое или двоичное изображение.
Мы также можем получить доступ к области изображения (широко известной как область интереса ROI), используя срез Numpy. Для этого мы должны предоставить координаты верхнего левого угла и нижнего правого угла. Давайте посмотрим на практику.
# Access single pixel px = image[50, 100] # Access an ROI roi = image[50:100, 80:150]
В приведенном выше примере будет возвращен прямоугольник с верхним левым углом (80, 50) и нижним правым углом (150, 100).
Разделение каналов
Если у нас есть цветное изображение, мы можем разделить эти каналы с помощью OpenCV и при необходимости работать с каждым из них отдельно. Это можно легко сделать с помощью метода OpenCV split()
. После этого мы также можем объединить их, используя метод OpenCV merge()
.
# Read the image image = cv2.imread('path/to/image') # Split channels blue, green, red = cv2.split(image) # print the shape of the blue channel which should be (width, height) which # is the same for all channels print(blue.shape) # ... You can change on this channels here # Then you can merge them to get an image new_image = cv2.merge((blue, green, red))
Мы также можем получить доступ к этим каналам таким же образом, используя срез массива Numpy.
blue = image[:, :, 0] green = image[:, :, 1] red = image[:, :, 2]
Все материалы этой серии доступны в этом репозитории Github.
Если вы считаете эту статью полезной, пожалуйста, похлопайте ее и следуйте за мной, чтобы узнать больше о вероятности. , линейная алгебра, математический анализ, машинное обучение, глубокое обучение и компьютерное зрение,…