Почему применение одного и того же канала трижды приводит к получению черно-белого изображения?
Я экспериментировал с обменом цветов с помощью 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)