Konvertieren von RGB in Graustufen / Intensität


128

Bei der Konvertierung von RGB in Graustufen sollten bestimmte Gewichte für die Kanäle R, G und B angewendet werden. Diese Gewichte sind: 0,2989, 0,5870, 0,1140.

Es wird gesagt, dass der Grund dafür die unterschiedliche menschliche Wahrnehmung / Sensibilität gegenüber diesen drei Farben ist. Manchmal wird auch gesagt, dass dies die Werte sind, die zur Berechnung des NTSC-Signals verwendet werden.

Allerdings habe ich im Web keine gute Referenz dafür gefunden. Woher stammen diese Werte?

Siehe auch diese vorherigen Fragen: hier und hier .


26
Ja tut es. Ich programmiere die ganze Zeit auf RGB-Werten. Das Anwenden von "realen" Werten auf diese Berechnungen ist sehr wichtig, wenn Sie möchten, dass Ihre App ihr Geld wert ist.
Neil N

1
Viele Programmierer mögen sich nicht darum kümmern und "falsche" Graustufenbilder berechnen, aber ich tue es.
Ypnos

6
Ich würde zustimmen, dass es sich um eine Codierung handelt - trotzig ein interessantes und relevantes Problem, wenn Sie Grafiken codieren. +1, da ich die Antwort selbst wissen möchte
Cruachan

6
RGB ist programmierbezogen. Es ist so programmierbezogen wie das Parsen von Datumszeichenfolgen. Als Konvertierung des Textes "true" in einen booleschen Wert.
Neil N

Antworten:


87

Die spezifischen Nummern in der Frage stammen von CCIR 601 (siehe den Wikipedia-Link unten).

Wenn Sie RGB -> Graustufen mit leicht unterschiedlichen Zahlen / Methoden konvertieren, werden Sie auf einem normalen Computerbildschirm unter normalen Lichtbedingungen überhaupt keinen großen Unterschied feststellen - probieren Sie es aus.

Hier sind einige weitere Links zur Farbe im Allgemeinen:

Wikipedia Luma

Bruce Lindblooms herausragende Website

Kapitel 4 über Farbe in dem Buch von Colin Ware, "Information Visualization", isbn 1-55860-819-2; Dieser lange Link zu Ware in books.google.com funktioniert möglicherweise nicht

cambridgeincolor : Hervorragende, gut geschriebene "Tutorials zum Erfassen, Interpretieren und Verarbeiten digitaler Fotos mit einem visuell orientierten Ansatz, bei dem Konzept über Verfahren steht"

Sollten Sie auf "lineares" oder "nichtlineares" RGB stoßen, ist hier ein Teil einer alten Notiz für mich. Wiederholen Sie, in der Praxis werden Sie keinen großen Unterschied sehen.


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

In der Farbwissenschaft werden die üblichen RGB-Werte wie in HTML-RGB (10%, 20%, 30%) als "nichtlinear" oder Gammakorrigiert bezeichnet . "Lineare" Werte sind definiert als

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

Dabei ist Gamma für viele PCs 2,2. Die üblichen RGB werden manchmal als R 'G' B '(R' = Rlin ^ (1 / Gamma)) geschrieben (puristischer Zungenklick), aber hier werde ich das 'fallen lassen.

Die Helligkeit auf einer CRT-Anzeige ist proportional zu RGBlin = RGB ^ gamma, sodass 50% Grau auf einer CRT ziemlich dunkel sind: 0,5 ^ 2,2 = 22% der maximalen Helligkeit. (LCD-Anzeigen sind komplexer; außerdem kompensieren einige Grafikkarten Gamma.)

Um das L*von RGB aufgerufene Maß für die Helligkeit zu erhalten , teilen Sie zuerst RGB durch 255 und berechnen Sie

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

Dies ist Yim XYZ-Farbraum; es ist ein Maß für die Farbleuchtdichte. (Die realen Formeln sind nicht genau x ^ gamma, sondern nahe; bleiben Sie für einen ersten Durchgang bei x ^ gamma.)

Schließlich,

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

"... strebt nach Wahrnehmungsgleichmäßigkeit [und] passt eng zur menschlichen Wahrnehmung von Leichtigkeit." - Wikipedia Lab Farbraum


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

14

Ich fand heraus, dass diese Veröffentlichung in einer Antwort auf eine frühere ähnliche Frage referenziert wurde. Es ist sehr hilfreich:

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

Es zeigt "Tonnen" verschiedener Methoden, um Graustufenbilder mit unterschiedlichen Ergebnissen zu erzeugen!


9

Hier ist ein Code in c, um RGB in Graustufen umzuwandeln. Die tatsächliche Gewichtung, die für die Umwandlung von RGB in Graustufen verwendet wird, beträgt 0,3R + 0,6G + 0,11B. Diese Gewichte sind nicht absolut kritisch, so dass Sie mit ihnen spielen können. Ich habe sie 0,25R + 0,5G + 0,25B gemacht. Es entsteht ein etwas dunkleres Bild.

HINWEIS: Der folgende Code nimmt das xRGB 32-Bit-Pixelformat an

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 nicht zu 1 hinzufügen. Wikipedia scheint 0,30 0,59 0,11 vorzuschlagen.
Damix911

Stimmt, aber das einzige Ergebnis, wenn sie nicht zu 1 addieren, ist eine geringfügige Änderung der Intensität. Die vorgeschlagene Methode von 0,25,0,5,0,25 addiert sich zwar zu 1, aber es wäre egal, wenn dies nicht der Fall wäre. Es ist eine Optimierung, daher ist es ein vernünftiger Kompromiss, ein kleines Stück Genauigkeit aufzugeben.
Twerdster

2
@twerdster Keiner der Koeffizientensätze ist korrekt. .3, .6, .11 ist der alte NTSC-Standard, nicht sRGB / Rec709 (was das Web und die meisten Computer verwenden). Und Ihre 0,25,0,5,0,25 ist kein vernünftiger Kompromiss - B ist nur 7% der Luminanz, Sie liegen um 347% falsch. Die Koeffizienten für sRGB / r709 (nach Linearisierung): Rlin * 0,2126 + Glin * 0,7152 + Blin * 0,0722 = Y Diese spektralen Gewichtungen werden aus der menschlichen spektralen Wahrnehmung abgeleitet. Sie können nicht einfach in der von Ihnen gewünschten Anzahl jammen und hoffen, genau zu sein. Sie müssen sRGB linearisieren und dann die richtigen Koeffizienten anwenden.
Myndex

Wenn Sie sich in einer Situation befinden, in der das Teilen zu teuer ist, lautet eine Näherung, bei der eine einzelne Multiplikation mit Verschiebungen und Additionen verwendet wird : 0.11111111 * ((G + (G<<1) + R) <<1) + B). Dies entspricht (2*R+6*G+B) / 9)oder 0.222 R + 0.666 G + 0.111 B. Vergleichen Sie vor Produktionsbeginn eine genaue Formel für verschiedene Testfälle.
ToolmakerSteve


6

Weitere Informationen hierzu finden Sie in den Farb-FAQ . Diese Werte stammen aus der Standardisierung von RGB-Werten, die wir in unseren Anzeigen verwenden. Laut den häufig gestellten Fragen zu Farben sind die von Ihnen verwendeten Werte veraltet, da es sich um die Werte handelt, die für den ursprünglichen NTSC-Standard und nicht für moderne Monitore verwendet werden.


3

Woher stammen diese Werte?

Die "Quelle" der angegebenen Koeffizienten sind die NTSC-Spezifikationen, die in Rec601 und Eigenschaften des Fernsehens zu sehen sind .

Die "ultimative Quelle" sind die CIE-Experimente zur menschlichen Farbwahrnehmung um 1931. Die spektrale Reaktion des menschlichen Sehens ist nicht einheitlich. Experimente führten zur Gewichtung von Tristimuluswerten basierend auf der Wahrnehmung. Unsere L-, M- und S-Kegel 1 sind empfindlich gegenüber den Lichtwellenlängen, die wir als "Rot", "Grün" bzw. "Blau" identifizieren. Hier werden die Tristimulus-Primärfarben abgeleitet. 2

Die spektralen Gewichtungen des linearen Lichts 3 für sRGB (und Rec709) sind:

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

Diese sind spezifisch für die sRGB- und Rec709-Farbräume, die Computermonitore (sRGB) oder HDTV-Monitore (Rec709) darstellen sollen, und sind in den ITU-Dokumenten für Rec709 sowie in BT.2380-2 (10/2018) aufgeführt.

Fußnoten (1) Zapfen sind die farbdetektierenden Zellen der Netzhaut des Auges.
(2) Die gewählten Tristimuluswellenlängen befinden sich jedoch NICHT auf dem "Peak" jedes Kegeltyps - stattdessen werden Tristimuluswerte so gewählt, dass sie auf einem bestimmten Kegeltyp wesentlich stärker stimulieren als auf einem anderen, dh eine Trennung des Stimulus.
(3) Sie müssen Ihre sRGB-Werte linearisieren, bevor Sie die Koeffizienten anwenden. Ich diskutiere dies in einer anderen Antwort hier.


-2

Diese Werte variieren von Person zu Person, insbesondere für Menschen, die farbenblind sind.


-4

Ist dies alles wirklich notwendig, variieren die menschliche Wahrnehmung und CRT vs LCD, aber die RGB-Intensität nicht. Warum nicht L = (R + G + B)/3und setzen Sie das neue RGB auf L, L, L?


3
Durch einfaches Mitteln aller drei R-, G- und B-Primärfarben werden sie als wahrnehmungsmäßig gleich behandelt, was für das menschliche Sichtsystem nicht der Fall ist.
Bill Feth
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.