В последней статье мы определили изображения, представили 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.

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