Преобразование RGB в оттенки серого / интенсивность

Говорят, что при преобразовании из RGB в оттенки серого необходимо применять конкретные веса для каналов R, G и B. Эти веса: 0,2989, 0,5870, 0,1140.

Говорят, что причиной этого является различное восприятие / восприятие человеком этих трех цветов. Иногда также говорят, что это значения, используемые для вычисления сигнала NTSC.

Тем не менее, я не нашел хорошую ссылку для этого в Интернете. Каков источник этих ценностей?

Смотрите также эти предыдущие вопросы: здесь и здесь.

9 ответов

Решение

Конкретные цифры в вопросе взяты из CCIR 601 (см. Ссылку на Википедию ниже).

Если вы конвертируете RGB -> оттенки серого с немного другими числами / разными методами, вы не увидите большой разницы на обычном экране компьютера при нормальных условиях освещения - попробуйте.

Вот еще несколько ссылок на цвет в целом:

Википедия Лума

Выдающийся веб-сайт Брюса Линдблума

глава 4 о цвете в книге Колина Уэра "Визуализация информации", исбн 1-55860-819-2; эта длинная ссылка на Ware в books.google.com может работать, а может и не работать

cambridgeincolor: превосходные, хорошо написанные "учебные пособия о том, как приобретать, интерпретировать и обрабатывать цифровые фотографии, используя визуально ориентированный подход, который подчеркивает концепцию над процедурой"

Если вы столкнетесь с "линейным" и "нелинейным" RGB, вот часть старой заметки для меня об этом. Повторите, на практике вы не увидите большой разницы.


RGB -> ^ гамма -> Y -> L*

В науке о цвете общие значения RGB, такие как html rgb( 10%, 20%, 30%), называются "нелинейными" или с гамма-коррекцией. "Линейные" значения определяются как

Rlin = R^gamma,  Glin = G^gamma,  Blin = B^gamma

где гамма 2,2 для многих ПК. Обычный RGB иногда пишется как R' G' B' (R' = Rlin ^ (1/gamma)) (пуристский щелчок по языку), но здесь я опущу '.

Яркость на ЭЛТ-дисплее пропорциональна RGBlin = RGB ^ гамма, поэтому 50% серого на ЭЛТ довольно темное: .5 ^ 2.2 = 22% от максимальной яркости. (ЖК-дисплеи более сложные; кроме того, некоторые видеокарты компенсируют гамму.)

Чтобы получить меру легкости называется L* из RGB, сначала разделите RGB на 255 и вычислите

Y = .2126 * R^gamma + .7152 * G^gamma + .0722 * B^gamma

Это Y в цветовом пространстве XYZ; это мера цвета "яркость". (Реальные формулы не совсем x^gamma, но близки; придерживайтесь x ^ gamma для первого прохода.)

В заключение,

L* = 116 * Y ^ 1/3 - 16

"... стремится к единообразию восприятия [и] близко соответствует восприятию человеком легкости". - Википедия Лаборатория цветового пространства

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

http://cadik.posvete.cz/color_to_gray_evaluation/

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

Вот некоторый код в c для преобразования rgb в оттенки серого. Реальное значение веса, используемое для преобразования rgb в оттенки серого, составляет 0.3R+0.6G+0.11B. эти веса не являются абсолютно критическими, поэтому вы можете играть с ними. Я сделал их 0,25R+ 0,5G+0,25B. Это производит немного более темное изображение.

ПРИМЕЧАНИЕ. Следующий код предполагает 32-битный формат xRGB

unsigned int *pntrBWImage=(unsigned int*)..data pointer..;  //assumes 4*width*height bytes with 32 bits i.e. 4 bytes per pixel
unsigned int fourBytes;
        unsigned char r,g,b;
        for (int index=0;index<width*height;index++)
        {
            fourBytes=pntrBWImage[index];//caches 4 bytes at a time
            r=(fourBytes>>16);
            g=(fourBytes>>8);
            b=fourBytes;

            I_Out[index] = (r >>2)+ (g>>1) + (b>>2); //This runs in 0.00065s on my pc and produces slightly darker results
            //I_Out[index]=((unsigned int)(r+g+b))/3;     //This runs in 0.0011s on my pc and produces a pure average
        }

Вот документ о том, как эти числа (или аналогичные) были получены:

https://web.archive.org/web/20160303201512/http://www.cis.rit.edu/mcsl/research/broadbent/CIE1931_RGB.pdf

Проверьте Цвет FAQ для информации об этом. Эти значения происходят от стандартизации значений RGB, которые мы используем в наших дисплеях. На самом деле, согласно Color FAQ, используемые вами значения устарели, так как они являются значениями, используемыми для исходного стандарта NTSC, а не для современных мониторов.

Каков источник этих ценностей?

"Источник" опубликованных коэффициентов - это спецификации NTSC, которые можно увидеть в Rec601 и " Характеристики телевидения".

"Окончательным источником" являются эксперименты CIE около 1931 года по человеческому восприятию цвета. Спектральная реакция человеческого зрения неоднородна. Эксперименты привели к взвешиванию значений тристимула на основе восприятия. Наши конусы L, M и S1 чувствительны к длинам световых волн, которые мы идентифицируем как "красный", "зеленый" и "синий" (соответственно), и именно здесь получены первичные цвета трехцветного стимула.2

Линейные световые3 спектральные весовые коэффициенты для sRGB (и Rec709):

Rlin * 0,2126 + Glin * 0,7152 + Blin * 0,0722 = Y

Они относятся к цветовым пространствам sRGB и Rec709, которые предназначены для представления мониторов компьютеров (sRGB) или HDTV (Rec709), и подробно описаны в документах МСЭ для Rec709, а также BT.2380-2 (10/2018)

СНОСКИ (1) Колбочки - это клетки, определяющие цвет сетчатки глаза.
(2) Тем не менее, выбранные тристимульные длины волн НЕ находятся на "пике" каждого типа конуса - вместо этого тристимульные значения выбираются таким образом, чтобы они стимулировали определенный тип конуса существенно больше, чем другой, то есть разделение стимула.
(3) Вам необходимо линеаризовать ваши значения sRGB перед применением коэффициентов. Я обсуждаю это в другом ответе здесь.

Начнем список, чтобы перечислить, как это делают разные программные пакеты. Вот и хорошая статья CVPR, которую стоит прочитать .

FreeImage

      #define LUMA_REC709(r, g, b)    (0.2126F * r + 0.7152F * g + 0.0722F * b)
#define GREY(r, g, b) (BYTE)(LUMA_REC709(r, g, b) + 0.5F)

OpenCV

Примитивы производительности nVidia

Примитивы производительности Intel

Matlab

      nGray =  0.299F * R + 0.587F * G + 0.114F * B; 

Эти значения варьируются от человека к человеку, особенно для людей, страдающих дальтонизмом.

Все это действительно необходимо, человеческое восприятие и ЭЛТ против ЖКД будет меняться, но интенсивность R G B нет, почему бы и нет L = (R + G + B)/3 и установить новый R G B на L, L, L?

Другие вопросы по тегам