Conversione da RGB a scala di grigi / intensità


129

Quando si converte da RGB a scala di grigi, si dice che devono essere applicati pesi specifici ai canali R, G e B. Questi pesi sono: 0,2989, 0,5870, 0,1140.

Si dice che la ragione di ciò sia la diversa percezione / sensibilità umana verso questi tre colori. A volte si dice anche che questi sono i valori usati per calcolare il segnale NTSC.

Tuttavia, non ho trovato un buon riferimento per questo sul web. Qual è l'origine di questi valori?

Vedi anche queste domande precedenti: qui e qui .


26
Sì lo fa. Faccio sempre programmazione su valori RGB. L'applicazione di valori "del mondo reale" a questi calcoli è molto importante se vuoi che la tua app sia degna di questo nome.
Neil N

1
Molti programmatori potrebbero non interessarsi e calcolare immagini in scala di grigi "sbagliate", ma io sì.
ypnos

6
Sono d'accordo che è correlato alla codifica - con aria di sfida un problema interessante e rilevante se stai codificando la grafica. +1 dato che vorrei conoscere la risposta da solo
Cruachan

6
RGB è correlato alla programmazione. È correlato alla programmazione come l'analisi delle stringhe di data. Come convertire il testo "true" in un valore booleano.
Neil N

Risposte:


87

I numeri specifici nella domanda provengono da CCIR 601 (vedere il collegamento di Wikipedia di seguito).

Se converti RGB -> scala di grigi con numeri leggermente diversi / metodi diversi, non vedrai molta differenza sullo schermo di un normale computer in condizioni di illuminazione normali: provalo.

Ecco alcuni altri link sul colore in generale:

Wikipedia Luma

L'eccezionale sito web di Bruce Lindbloom

il capitolo 4 sul colore nel libro di Colin Ware, "Information Visualization", isbn 1-55860-819-2; questo lungo link a Ware in books.google.com potrebbe o non potrebbe funzionare

cambridgeincolor : "tutorial eccellenti e ben scritti su come acquisire, interpretare ed elaborare fotografie digitali utilizzando un approccio visivamente orientato che enfatizza il concetto sulla procedura"

Se dovessi imbatterti in RGB "lineare" o "non lineare", ecco parte di una vecchia nota a me stesso su questo. Ripeti, in pratica non vedrai molta differenza.


RGB -> ^ gamma -> Y -> L *

Nella scienza del colore, i valori RGB comuni, come in html rgb (10%, 20%, 30%), sono chiamati "non lineari" o con correzione gamma . I valori "lineari" sono definiti come

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

dove gamma è 2.2 per molti PC. I soliti RGB a volte sono scritti come R 'G' B '(R' = Rlin ^ (1 / gamma)) (clic con la lingua dei puristi) ma qui lascerò cadere il '.

La luminosità su un display CRT è proporzionale a RGBlin = RGB ^ gamma, quindi il 50% di grigio su un CRT è piuttosto scuro: 0,5 ^ 2,2 = 22% della luminosità massima. (I display LCD sono più complessi; inoltre, alcune schede grafiche compensano la gamma.)

Per ottenere la misura della luminosità chiamata L*da RGB, prima dividi RGB per 255 e calcola

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

Questo è Ynello spazio colore XYZ; è una misura della "luminanza" del colore. (Le vere formule non sono esattamente x ^ gamma, ma vicine; attenersi a x ^ gamma per un primo passaggio.)

Finalmente,

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

"... aspira all'uniformità percettiva [e] corrisponde strettamente alla percezione umana della leggerezza." - Spazio colore Wikipedia Lab


8
Y = 0,2126 * R + 0,7152 * G + 0,0722 * B - Wikipedia ( en.wikipedia.org/wiki/Grayscale )
iamantony


9

Ecco del codice in c per convertire rgb in scala di grigi. La ponderazione reale utilizzata per la conversione da rgb a scala di grigi è 0,3R + 0,6G + 0,11B. questi pesi non sono assolutamente critici, quindi puoi giocarci. Li ho fatti 0.25R + 0.5G + 0.25B. Produce un'immagine leggermente più scura.

NOTA: il codice seguente presuppone il formato pixel xRGB a 32 bit

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
        }

2
0.3 0.6 0.11 non aggiungere a 1. Wikipedia sembra suggerire 0.30 0.59 0.11.
damix911

Vero, ma l'unico risultato se non si aggiungono a 1 sarà un leggero cambiamento di intensità. Il metodo proposto di 0.25,0.5,0.25 aggiunge a 1 ma non avrebbe importanza se non lo facesse. È un'ottimizzazione, quindi rinunciare a un po 'di precisione è un compromesso ragionevole.
twerdster

2
@twerdster Nessuno dei due gruppi di coefficienti è corretto. .3, .6, .11 è il vecchio standard NTSC, non sRGB / Rec709 (che è quello utilizzato dal Web e dalla maggior parte dei computer). E il tuo 0.25,0.5,0.25 non è un compromesso ragionevole: B è solo il 7% della luminanza, ti sbagli del 347%. I coefficienti per sRGB / r709 (dopo la linearizzazione): Rlin * 0,2126 + Glin * 0,7152 + Blin * 0,0722 = Y Queste ponderazioni spettrali derivano dalla percezione spettrale umana. Non puoi semplicemente inceppare in qualsiasi numero desideri per comodità e sperare di essere accurato. È necessario linearizzare sRGB e quindi applicare i coefficienti corretti.
Myndex

Se vi trovate in una situazione in cui divario è troppo costoso, un'approssimazione che utilizza un singolo moltiplicano con turni e aggiunge è: 0.11111111 * ((G + (G<<1) + R) <<1) + B). Questo è equivalente a (2*R+6*G+B) / 9)o 0.222 R + 0.666 G + 0.111 B. Prima di passare alla produzione, confrontare con una formula accurata per vari casi di test.
ToolmakerSteve


6

Consulta le Domande frequenti sul colore per informazioni su questo. Questi valori derivano dalla standardizzazione dei valori RGB che utilizziamo nei nostri display. In realtà, secondo le Domande frequenti sul colore, i valori che stai utilizzando sono obsoleti, in quanto sono i valori utilizzati per lo standard NTSC originale e non per i monitor moderni.


3

Qual è l'origine di questi valori?

La "fonte" dei coefficienti pubblicati sono le specifiche NTSC che possono essere viste in Rec601 e Caratteristiche della televisione .

La "fonte ultima" sono gli esperimenti CIE intorno al 1931 sulla percezione umana del colore. La risposta spettrale della visione umana non è uniforme. Gli esperimenti hanno portato alla ponderazione dei valori di tristimolo in base alla percezione. I nostri coni L, M e S 1 sono sensibili alle lunghezze d'onda della luce che identifichiamo come "Rosso", "Verde" e "Blu" (rispettivamente), da cui derivano i colori primari del tristimolo. 2

Le ponderazioni spettrali della luce lineare 3 per sRGB (e Rec709) sono:

R lin * 0,2126 + G lin * 0,7152 + B lin * 0,0722 = Y

Questi sono specifici per gli spazi colore sRGB e Rec709, che hanno lo scopo di rappresentare monitor di computer (sRGB) o monitor HDTV (Rec709) e sono descritti in dettaglio nei documenti ITU per Rec709 e anche BT.2380-2 (10/2018)

NOTE A PIEDI (1) I coni sono le cellule che rilevano il colore della retina dell'occhio.
(2) Tuttavia, le lunghezze d'onda del tristimolo scelte NON sono al "picco" di ciascun tipo di cono - invece i valori di tristimolo sono scelti in modo tale da stimolare su un particolare tipo di cono sostanzialmente più di un altro, cioè separazione dello stimolo.
(3) È necessario linearizzare i valori sRGB prima di applicare i coefficienti. Ne discuto in un'altra risposta qui.


-2

Questi valori variano da persona a persona, specialmente per le persone daltoniche.


-4

è tutto questo davvero necessario, la percezione umana e CRT vs LCD varieranno, ma l'intensità RGB no, perché no L = (R + G + B)/3e impostare il nuovo RGB su L, L, L?


3
La semplice media di tutte e tre le primarie R, G, B le tratta come percettivamente uguali, il che non è il caso del sistema di visione umano.
Bill Feth
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.