Konwersja RGB na skalę szarości / intensywność


129

Podczas konwersji z RGB do skali szarości mówi się, że należy zastosować określone wagi do kanałów R, G i B. Te wagi to: 0,2989, 0,5870, 0,1140.

Mówi się, że przyczyną tego jest inna percepcja / wrażliwość człowieka na te trzy kolory. Czasami mówi się również, że są to wartości używane do obliczania sygnału NTSC.

Jednak nie znalazłem dobrego odniesienia do tego w Internecie. Jakie jest źródło tych wartości?

Zobacz także te poprzednie pytania: tutaj i tutaj .


26
Tak. Cały czas programuję na wartościach RGB. Stosowanie wartości „ze świata rzeczywistego” do tych obliczeń jest bardzo ważne, jeśli chcesz, aby Twoja aplikacja była warta swojej ceny.
Neil N

1
Wielu programistów może nie przejmować się i obliczać „niewłaściwe” obrazy w skali szarości, ale ja tak.
ypnos

6
Zgadzam się, że jest to związane z kodowaniem - zdecydowanie interesujący i istotny problem, jeśli kodujesz grafikę. +1, ponieważ sam chciałbym znać odpowiedź
Cruachan

6
RGB jest związane z programowaniem. Jest to tak samo związane z programowaniem, jak analizowanie ciągów dat. Konwersja tekstu „true” na wartość logiczną.
Neil N

Odpowiedzi:


87

Konkretne liczby w pytaniu pochodzą z CCIR 601 (patrz link do Wikipedii poniżej).

Jeśli przekonwertujesz RGB -> skalę szarości z nieco innymi liczbami / różnymi metodami, nie zobaczysz dużej różnicy na normalnym ekranie komputera w normalnych warunkach oświetleniowych - spróbuj.

Oto kilka ogólnych linków dotyczących koloru:

Wikipedia Luma

Znakomita witryna internetowa Bruce'a Lindblooma

rozdział 4 o kolorze w książce Colina Ware'a „Wizualizacja informacji”, isbn 1-55860-819-2; ten długi link do Ware w books.google.com może, ale nie musi, działać

cambridgeincolor : doskonałe, dobrze napisane „samouczki dotyczące pozyskiwania, interpretowania i przetwarzania fotografii cyfrowych przy użyciu podejścia zorientowanego wizualnie, które kładzie nacisk na koncepcję nad procedurę”

Jeśli napotkasz „liniowe” i „nieliniowe” RGB, oto część mojej starej notatki na ten temat. Powtarzam, w praktyce nie zobaczysz dużej różnicy.


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

W nauce o kolorach typowe wartości RGB, takie jak html rgb (10%, 20%, 30%), nazywane są „nieliniowymi” lub z korekcją gamma . Wartości „liniowe” są zdefiniowane jako

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

gdzie gamma wynosi 2,2 dla wielu komputerów. Zwykłe RGB jest czasami zapisywane jako R 'G' B '(R' = Rlin ^ (1 / gamma)) (purystyczne kliknięcie językiem), ale tutaj zostawię '.

Jasność na ekranie CRT jest proporcjonalna do RGBlin = RGB ^ gamma, więc 50% szarości na CRT jest dość ciemne: .5 ^ 2,2 = 22% maksymalnej jasności. (Wyświetlacze LCD są bardziej złożone; ponadto niektóre karty graficzne kompensują gamma).

Aby uzyskać miarę jasności wywołaną L*z RGB, najpierw podziel RGB przez 255 i oblicz

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

To jest Yw przestrzeni kolorów XYZ; jest miarą „luminancji” koloru. (Prawdziwe formuły nie są dokładnie x ^ gamma, ale bliskie; trzymaj się x ^ gamma dla pierwszego przebiegu).

Wreszcie,

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

„… dąży do jednorodności percepcji [i] ściśle pasuje do ludzkiego postrzegania lekkości”. - Przestrzeń kolorów Laboratorium Wikipedii


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


9

Oto kod w c do konwersji rgb na skalę szarości. Rzeczywista waga użyta do konwersji rgb do skali szarości to 0,3R + 0,6G + 0,11B. te wagi nie są absolutnie krytyczne, więc możesz się nimi bawić. Zrobiłem je 0,25R + 0,5G + 0,25B. Daje nieco ciemniejszy obraz.

UWAGA: W poniższym kodzie założono, że 32-bitowy format pikseli 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
        }

2
0,3 0,6 0,11 nie dodawaj do 1. Wikipedia wydaje się sugerować 0,30 0,59 0,11.
damix911

To prawda, ale jedynym skutkiem ich nie dodania do 1 będzie bardzo niewielka zmiana intensywności. Proponowana metoda 0,25, 0,5, 0,25 dodaje się do 1, ale nie miałoby znaczenia, gdyby tak się nie stało. Jest to optymalizacja, więc rezygnacja z odrobiny dokładności jest rozsądnym kompromisem.
twerdster

2
@twerdster Żaden zestaw współczynników nie jest poprawny. .3, .6, .11 to stary standard NTSC, a nie sRGB / Rec709 (z którego korzysta Internet i większość komputerów). A twoje 0,25,0,5,0,25 nie jest rozsądnym kompromisem - B to tylko 7% luminancji, mylisz się o 347%. Współczynniki dla sRGB / r709 (po linearyzacji): Rlin * 0,2126 + Glin * 0,7152 + Blin * 0,0722 = Y Te wagi widmowe pochodzą z ludzkiej percepcji spektralnej. Nie możesz po prostu zagrać w dowolne liczby dla wygody i mieć nadzieję, że będziesz dokładny. Musisz zlinearyzować sRGB, a następnie zastosować odpowiednie współczynniki.
Myndex

Jeśli jesteś w sytuacji, gdy podział jest zbyt kosztowne, przybliżenie, które wykorzystuje pojedynczy pomnożyć przesunięć i dodaje się: 0.11111111 * ((G + (G<<1) + R) <<1) + B). Jest to równoważne z (2*R+6*G+B) / 9)lub 0.222 R + 0.666 G + 0.111 B. Przed przystąpieniem do produkcji porównaj z dokładnym wzorem dla różnych przypadków testowych.
ToolmakerSteve


6

Sprawdź często zadawane pytania dotyczące kolorów, aby uzyskać informacje na ten temat. Wartości te pochodzą ze standaryzacji wartości RGB, których używamy w naszych wyświetlaczach. W rzeczywistości, zgodnie z często zadawanymi pytaniami dotyczącymi kolorów, używane wartości są nieaktualne, ponieważ są to wartości używane w oryginalnym standardzie NTSC, a nie w nowoczesnych monitorach.


3

Jakie jest źródło tych wartości?

„Źródłem” opublikowanych współczynników są specyfikacje NTSC, które można zobaczyć w Rec601 i „ Charakterystyka telewizji” .

„Ostatecznym źródłem” są eksperymenty CIE z około 1931 r. Dotyczące postrzegania kolorów przez ludzi. Odpowiedź spektralna ludzkiego wzroku nie jest jednolita. Eksperymenty doprowadziły do ​​wyważenia wartości trójbodźca na podstawie percepcji. Nasze stożki L, M i S 1 są wrażliwe na długości fal światła, które identyfikujemy jako „czerwony”, „zielony” i „niebieski” (odpowiednio), z których pochodzą podstawowe kolory trójchromatyczne. 2

Wagi widmowe linear light 3 dla sRGB (i Rec709) to:

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

Są one specyficzne dla przestrzeni kolorów sRGB i Rec709, które mają reprezentować monitory komputerowe (sRGB) lub monitory HDTV (Rec709) i są szczegółowo opisane w dokumentach ITU dla Rec709, a także BT.2380-2 (10/2018)

PRZYPISY (1) Czopki to komórki siatkówki oka wykrywające kolor.
(2) Jednak wybrane długości fal trójchromatycznych NIE znajdują się na „szczycie” każdego typu czopków - zamiast tego wartości trójbodźców są tak dobrane, że stymulują one na konkretnym typie czopków znacznie bardziej niż inne, tj. Oddzielenie bodźca.
(3) Musisz zlinearyzować wartości sRGB przed zastosowaniem współczynników. Omawiam to w innej odpowiedzi tutaj.


-2

Wartości te różnią się w zależności od osoby, szczególnie w przypadku osób ze ślepotą na kolory.


-4

czy to wszystko jest naprawdę konieczne, ludzka percepcja i CRT vs LCD będą się różnić, ale intensywność RGB nie, dlaczego nie L = (R + G + B)/3i ustawić nowy RGB na L, L, L?


3
Zwykłe uśrednienie wszystkich trzech prawyborów R, G, B traktuje je jako percepcyjnie równe, co nie ma miejsca w przypadku ludzkiego systemu widzenia.
Bill Feth
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.