A conversão de RGB para tons de cinza / intensidade
-
22-08-2019 - |
Pergunta
Quando a conversão de RGB para tons de cinzento, diz-se que os pesos específicos para os canais R, G e B deveria ser aplicada. Esses pesos são: 0,2989, 0,5870, 0,1140
.Diz-se que a razão para isso é diferente percepção humana / sensibilidade em relação a esses três cores. Às vezes também é dito estes são os valores usados ??para calcular o sinal NTSC.
No entanto, eu não encontrar uma boa referência para isso na web. Qual é a fonte desses valores?
Solução
Os números específicas na questão são do CCIR 601 (veja o link Wikipedia abaixo).
Se você converter RGB -> em tons de cinza com um pouco diferentes números / métodos diferentes, você não verá muita diferença em tudo na tela do computador normal, em condições normais de iluminação - experimentá-lo
.Aqui estão mais algumas ligações em cor em geral:
Bruce Lindbloom 's excelente web site
capítulo 4 em cores no livro de Colin Ware, "Visualização de Informação", ISBN 1-55860-819-2; esta longa ligação com Ware em books.google. com pode ou não trabalho
cambridgeincolor : excelente, bem escrito "Tutoriais sobre como adquirir, interpretar e processar fotografias digitais usando uma abordagem orientada visualmente que enfatiza conceito sobre procedimento "
Se você correr em "linear" vs "não-linear" RGB, aqui está parte de uma nota antiga para mim sobre isso. Repita, na prática, você não verá muita diferença.
RGB -> ^ gama -> Y -> * L
Na ciência da cor, os valores RGB comum, como em RGB HTML (10%, 20%, 30%), são chamados de "não-linear" ou gama corrigido . valores "linear" são definidos como
Rlin = R^gamma, Glin = G^gamma, Blin = B^gamma
onde gama é de 2,2 por muitos PCs. O habitual R G B são por vezes escrito como R 'G' B '(R' = RLIN ^ (1 / gama)) (Puristas da língua-click), mas aqui eu vou largar a'.
Brilho em um monitor CRT é proporcional à RGBlin = RGB ^ gama, assim 50% de cinza de um CRT é bastante escuro: 0,5 ^ 2,2 = 22% do brilho máximo. (Telas de LCD são mais complexas; Além disso, algumas placas gráficas compensar gama.)
Para obter a medida de leveza chamado L*
de RGB,
primeiro dividir R G B por 255, e de computação
Y = .2126 * R^gamma + .7152 * G^gamma + .0722 * B^gamma
Esta é Y
no espaço de cor XYZ; é uma medida de cor "luminância".
(As fórmulas reais não são exatamente x ^ gama, mas perto;
vara com x ^ gama para uma primeira passagem.)
Finalmente,
L* = 116 * Y ^ 1/3 - 16
"... aspira a uniformidade perceptual [e] se aproxima a percepção humana de leveza." - Lab espaço de cor
Outras dicas
Eu achei que esta publicação referenciada numa resposta a uma pergunta semelhante anterior. É muito útil:
http://cadik.posvete.cz/color_to_gray_evaluation/
Mostra 'toneladas' de diferentes métodos para gerar imagens em tons de cinza com resultados diferentes!
Heres algum código em C para rgb convertido em tons de cinza. A ponderação verdadeira usado para rgb para conversão de tons de cinza é 0.3R + 0.6G + 0.11B. estes pesos Arent absolutamente crítico para que possa jogar com eles. Fiz-lhes 0.25R + 0.5G + 0.25B. Ele produz uma imagem um pouco mais escura.
NOTA: O código a seguir assume formato xRGB de pixel de 32 bits
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
}
Confira o Cor FAQ para informações sobre isso. Estes valores vêm da padronização de valores RGB que usamos em nossos monitores. Na verdade, de acordo com o FAQ cores, os valores que você está usando são desatualizados, pois eles são os valores usados ??para o padrão NTSC original e não os monitores modernos.
Aqui está um artigo sobre a forma como estes números (ou outros similares) foram derivados:
O que é a fonte desses valores?
A "fonte" dos coeficientes postadas são as especificações NTSC que pode ser visto em REC601 e Características de Televisão .
A "fonte final" são a CIE circa 1931 experimentos sobre percepção de cor humana. A resposta espectral da visão humana não é uniforme. Experimentos levou à ponderação dos valores tristimulares baseada na percepção. Nossa L, M e S cones 1 são sensíveis a comprimentos de onda de luz que se identificam como "Vermelho", "Verde" e "Azul" (respectivamente), que é onde as cores primárias tristimulares são derivadas . 2
A luz linear 3 espectral coeficientes para sRGB (e REC709) são:
R lin * + G 0,2126 lin * 0,7152 + B lin * 0,0722 = Y
Estas são específicos para os espaços de cores sRGB e REC709, que são destinados para representar monitores de computador (sRGB) ou monitores de HDTV (REC709), e são detalhados nos documentos da UIT para REC709 e também < a href = "https://www.itu.int/dms_pub/itu-r/opb/rep/R-REP-BT.2380-2-2018-PDF-E.pdf" rel = "nofollow noreferrer"> BT ,2380-2 (10/2018)
NOTAS
(1) Cones são a cor células de retina do olho detectar.
(2) No entanto, os comprimentos de onda escolhidos de triestímulo não são o "pico" de cada tipo cone - valores em vez de triestímulo são escolhidos de tal modo que eles estimulam em determinado tipo de cone substancialmente mais do que o outro, isto é, separação de estímulo
.
(3) Você precisa linearizar seus valores sRGB antes de aplicar os coeficientes. Discuto isso no outra resposta aqui.
Estes valores variam de pessoa para pessoa, especialmente para pessoas que são daltônicos.
é tudo isso realmente necessário, a percepção humana e CRT vs LCD irá variar, mas a intensidade R G B não faz, por que não L = (R + G + B)/3
e definir o novo RGB para L, L, L?