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

Я экспериментировал с обменом цветов с помощью 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)))

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

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

enter image description here

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

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

1 Ответ

0 голосов
/ 13 января 2019

Здесь нужно кое-что понять.

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

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

Жирный Выделение мое.

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

Второй

Существует несколько способов цветового кодирования. Наиболее выдающимся из них является 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)
...