[Обработка компьютерного зрения 4] Преобразование цветового пространства

задняя часть

Это 4-й день моего участия в августовском испытании обновлений.Подробности о событии:Испытание августовского обновления

преобразование цветового пространства

1. Работа со слоями

Как упоминалось в части 2, если это двоичное изображение (черно-белое изображение) или изображение в градациях серого, пикселю требуется 8-битное двоичное представление. Для цветных изображений пиксель должен быть представлен тремя 8-битными двоичными файлами. Мы думаем, что изображение в градациях серого имеет только один слой, в то время как обычное цветное изображение имеет три слоя.

Для изображений в градациях серого пиксель подчеркивает степень белизны.Когда значение пикселя равно 0, изображение выглядит черным, а когда значение пикселя равно 255, изображение кажется белым. Серый в середине можно понимать как «недостаточно белый цвет».

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

Итак, как вы работаете со слоями в OpenCV? Давайте сначала откроем цветное изображение и проверим его количество каналов:

import cv2
# 读取图片
img = cv2.imread("xyql.jpg")
# 查看图片的形状
print(img.shape)

Результат выглядит следующим образом:

(1079, 1080, 3)

3 — количество слоев в изображении. Мы можем разделить три канала по индексу:

import cv2
# 读取图片
img = cv2.imread('test.jpg')
# 切片提取B通道
b = img[:, :, 0]
# 切片提取G通道
g = img[:, :, 1]
# 切片提取R通道
r = img[:, :, 2]

Поскольку режим изображения по умолчанию в OpenCV — BGR, 0-й канал, который мы разделяем, — это b, а первый и второй — это g и r соответственно. Мы можем смотреть на изображение с тремя каналами:

在这里插入图片描述

Выше приведены исходное изображение и трехканальное изображение BGR соответственно. Поскольку разделенное изображение имеет только один канал, эффект отображения полностью черно-белый.

Видно, что лицо Наны на исходном изображении румяное, поэтому часть кожи R-канала должна быть ярче (цвет белее и значение пикселя выше).

Помимо индексации себя, мы также можем вызвать встроенный метод OpenCV для разделения каналов, код выглядит следующим образом:

import cv2
# 读取图片
img = cv2.imread('test.jpg')
# 调用OpenCV内置方法进行分离通道
b, g, r = cv2.split(img)

В коде мы вызываемcv2.split(), если у нашего изображения три канала, нам нужно получить его с тремя параметрами, если есть четыре канала, нам нужно получить его с четырьмя параметрами.

2. Цветовое пространство

До этого мы сталкивались с цветовыми пространствами, такими как RGB и GRAY. Кроме RGB и GRAY есть XYZ, YCrCb, HSV и т.д. Различные удаления цветового пространства решают разные проблемы, и иногда мы конвертируем изображение в указанное цветовое пространство для соответствующей обработки.

RGB (мы думаем, что RGB и BGR — это одно и то же цветовое пространство) — это удобное для обработки компьютерами цветовое пространство, состоящее из трех основных цветов. Но RGB — это цветовое пространство, которое трудно понять людям Мы не говорим, что желтый — это красный + зеленый, а белый — это красный + зеленый + синий (для обычных людей).

Цветовое пространство HSV — это модель, соответствующая зрительному восприятию человека.Это цветовое пространство использует оттенок (Hue, также известный как оттенок), насыщенность (Saturation) и яркость (Value) для представления пикселей. Их объяснения таковы:

Выдержка из «Легкое начало работы с OpenCV: для Python» Ли Лизонга.

● Оттенок: Оттенок связан с основной длиной волны света в смешанном спектре, например, «красный, оранжевый, желтый, зеленый, синий, фиолетовый» соответственно означает различные оттенки. С точки зрения длины волны разные длины волн света кажутся разными цветами, фактически они отражают разницу в оттенках.

● Насыщенность: Относится к относительной чистоте или количеству белого света, смешанного с цветом. Цвета чистого спектра полностью насыщены, а такие цвета, как темно-красный (красный плюс белый) и лавандовый (фиолетовый плюс белый), недонасыщены, а насыщенность обратно пропорциональна количеству добавляемого белого света.

● Яркость: отражает яркость света, воспринимаемого человеческими глазами, которая связана с отражательной способностью объектов. Для цвета, чем больше в него примешано белого, тем выше яркость, чем больше в него примешано черного, тем ниже яркость.

Если мы сталкиваемся со сценой, в которой необходимо настроить насыщенность, мы можем использовать цветовое пространство HSV.

3. Преобразование цветового пространства

Существуют фиксированные формулы преобразования цветовых пространств, эти формулы очень просты, давайте кратко рассмотрим одну из них. Преобразование цветового пространства RGB в YCrCb:

Y=0.299R+0.587G+0.114BCr=(RY)×0.713+δCb=(BY)×0.564+δY = 0,299·R+0,587·G+0,114·B\\ Cr=(R-Y)×0,713+\дельта\\ Cb=(B-Y)×0,564+\delta

где значение δ рассчитывается следующим образом:

δ={128,8битовая карта32768,16битовая карта0.5,изображение одинарной точности\delta = \begin{cases} 128, 8-битное изображение \\ 32768, 16-битное изображение \\ 0,5, изображение одинарной точности \\ \end{cases}

Конечно, нам не нужно вычислять его самостоятельно, функция преобразования цветового пространства предусмотрена в OpenCV.cv2.cvtColor(), формат функции следующий:

dst = cv2.cvtColor(src, code)

Эта функция принимает два параметра: изображение для преобразования и режим преобразования. Наконец, функция вернет нам преобразованный результат, здесь мы ориентируемся на параметр кода.

Для параметра кода нам нужно только добавить некоторые константы в OpenCV, которые легко понять:

在这里插入图片描述

Поскольку изображение относительно длинное, здесь указана только его часть. Большинство правил именования — COLOR_XX2YY, т. е. функция заключается в преобразовании изображения с цветовым пространством XX в цветовое пространство YY. Среди них наиболее часто используются следующие:

# 将BGR转换成GRAY(灰度图)
cv2.COLOR_BGR2GRAY
# 将BGR转换为RGB
cv2.COLOR_BGR2RGB
# 将BGR转换为HSV
cv2.COLOR_BGR2HSV
# 将BGR转换为BGRA(png图片)
cv2.COLOR_BGR2BGRA

Используем на практике, сначала рассмотрим простой код:

import cv2
import numpy as np
from PIL import Image
# 读取图片
img = Image.open('nn.jpg')
# 将图片对象转换成ndarray对象
img = np.array(img)
# 显示图片
cv2.imshow('img', img)
cv2.waitKey()
cv2.destroyAllWindows()

Вот исходное изображение и изображение, показанное кодом выше:

在这里插入图片描述

В коде мы используем модуль PIL для чтения изображения, потому что PIL по умолчанию читается в режиме RGB, поэтому, когда мы напрямую конвертируем его в массив ndarray, OpenCV меняет местами каналы R и B, поэтому цвет изображения отображается ненормально.

Установка модуля PIL выглядит следующим образом:

pip install pillow

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

Для правильного отображения нам нужно сделать несколько простых преобразований в цветовое пространство:

import cv2
import numpy as np
from PIL import Image
img = Image.open('nn.jpg')
img = np.array(img)
# 将RGB图片转换成BGR
bgr = cv2.cvtColor(img, cv2.COLOR_RGB2BGR)
cv2.imshow('img', bgr)
cv2.waitKey()
cv2.destroyAllWindows()

Вы можете попробовать запустить его самостоятельно, и эффект отображения будет таким же, как и исходное изображение. Преобразование других цветовых пространств такое же, и здесь не будет демонстрироваться одно за другим.

Для большего количества контента вы можете обратить внимание на личный публичный аккаунт «Новая папка X».