Почему применение одного и того же канала трижды приводит к получению черно-белого изображения?

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

import cv2

color = cv2.imread("lohri.jpg")
b,g,r = cv2.split(color)
swap = cv2.imwrite("swap.jpg", cv2.merge((r,g,b)))

Как вы видите выше, я поменял 2 цветовых канала на красный и синий. Но если я применяю только один канал, как показано ниже:

swap = cv2.imwrite("swap.jpg", cv2.merge((b,b,b)))

это приводит к черно-белому изображению. Я не мог понять почему. Может ли кто-нибудь помочь мне понять это?

Ниже приведено изображение, полученное в результате применения того же канала трижды.

Исходное изображение выглядело так:

Это происходит независимо от выбранного канала (r,g,b)

1 ответ

Здесь есть пара вещей, которые нужно понять.

Во-первых, мы должны обсудить, как работает цветовое кодирование. Исходная статья. Очень рекомендую прочитать

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

Жирный Акцент мой.

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

Во-вторых,

Существует несколько способов цветового кодирования. Наиболее выдающимся из них является RGB. Итак, мы здесь: RGB. R означает: красный. G означает: зеленый. B означает: синий. Цветовое кодирование RGB предполагает, что каждый цвет имеет три компонента: красный, зеленый и синий. Верьте или нет, все цвета, которые могут видеть люди, могут быть составлены из комбинации красного, зеленого и синего.

Здесь важно понять, что R,G,B - это всего лишь один способ представить эту "комбинацию" для каждого пикселя. Только комбинация дает нам цвета, которые мы видим на изображении.

В-третьих, в RGB числа представляют "количество" для этого компонента цвета / канала. 0 означает: ничего, 255 означает: максимальная сумма.

В-четвертых,

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

Второе наблюдение: Когда все три из R, G и B равны, мы получаем нейтральный цвет: белый, серый или черный.

Эта часть действительно важна для понимания. Поскольку значения R, G и B представляют только компоненты, они должны быть объединены на основе того, "сколько" каждого компонента присутствует. Если они присутствуют в равных количествах, все они генерируют что-то по оттенкам от черного к белому (обычно называемое оттенками серого). Чернота / белизна зависит от фактического числа для каждого канала, 0 будет черным, 255 белым, другие где-то посередине. Важно понимать, что это означает, что изображение все еще может иметь компоненты 3 R,G,B, но все они были установлены на одно и то же значение для пикселя с оттенками серого.

Теперь, углубившись в аспект кодирования, важно понять, что числа - это просто чистые числа.

import cv2

color = cv2.imread("lohri.jpg")
b,g,r = cv2.split(color)

Здесь b, g и r больше не являются чем-то особенным, это просто матрицы, хранящие числа, по одному на каждый пиксель. Я могу очень хорошо написать разные имена для них следующим образом:

import cv2

color = cv2.imread("lohri.jpg")
apple,mango,orange = cv2.split(color) #perfectly valid, although confusing

Понятно, что имена - это просто имена. Только "комбинации" в изображении придают им какое-либо значение. Итак, когда вы делаете этот шаг

swap = cv2.imwrite("swap.jpg", cv2.merge((b,b,b)))

Я очень хорошо могу написать это так

swap = cv2.imwrite("swap.jpg", cv2.merge((some_random_matrix,some_random_matrix,some_random_matrix)))

Или вот так,

swap = cv2.imwrite("swap.jpg", cv2.merge((apple,apple,apple)))

Важно понимать следующее: имя переменной b не имел абсолютно никакого значения сам по себе, это была просто матрица чисел. Когда вы используете функцию слияния и устанавливаете каждый канал R, G и B с одной и той же матрицей, вы фактически назначаете каждому пикселю одинаковые значения для каждого значения R,G,B. Как мы знаем раньше, когда каждый "канал" для пикселя имеет одинаковые значения, "комбинация" всегда является черно-белой (или оттенками серого).

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

Правильный способ - сохранить значения в синем канале, но установить для других каналов значение 0 для каждого пикселя. Установка всех каналов на одно и то же значение не дает вам "больше этого определенного цвета", потому что само значение не имеет значения, это просто "комбинация" значений в каждом канале.

color = cv2.imread('lohri.jpg')

new_image = color.copy()
# set green and red channels to 0
new_image[:, :, 1] = 0
new_image[:, :, 2] = 0
cv2.imwrite("only_blue.jpg", new_image)
Другие вопросы по тегам