Szukam jakiejś formuły lub algorytmu, aby określić jasność koloru, biorąc pod uwagę wartości RGB. Wiem, że to nie może być tak proste, jak sumowanie wartości RGB razem i posiadanie wyższych sum, by były jaśniejsze, ale jestem trochę niepewny, od czego zacząć.
387
Odpowiedzi:
Masz na myśli jasność? Czy postrzegasz jasność? Luminancja?
(0.2126*R + 0.7152*G + 0.0722*B)
[1](0.299*R + 0.587*G + 0.114*B)
[2]→sqrt( 0.241*R^2 + 0.691*G^2 + 0.068*B^2 )
sqrt( 0.299*R^2 + 0.587*G^2 + 0.114*B^2 )
(dzięki @MatthewHerbst ) [3]źródło
0.299*(R^2)
(ponieważ potęgowanie następuje przed pomnożeniem)Myślę, że szukasz formuły konwersji RGB -> Luma .
Fotometryczna / cyfrowa ITU BT.709 :
Cyfrowy ITU BT.601 (nadaje większą wagę komponentom R i B):
Jeśli chcesz wymienić dokładność za wykonanie, istnieją dwie formuły przybliżenia dla tego:
Można je szybko obliczyć jako
źródło
Blue
+ 3 * zielony) / 6, drugi to (3 * czerwony +Blue
+ 4 * zielony) >> 3. przyznane, w obu szybkich przybliżeniach, niebieski ma najniższą wagę, ale nadal tam jest.Y = (R<<1+R+G<<2+B)>>3
(to tylko 3-4 cykle procesora na ARM), ale myślę, że dobry kompilator zrobi to za ciebie.Dokonałem porównania trzech algorytmów w przyjętej odpowiedzi. Generowałem kolory cyklicznie, w których użyto tylko około 400 kolorów. Każdy kolor jest reprezentowany przez 2x2 pikseli, kolory są sortowane od najciemniejszego do najjaśniejszego (od lewej do prawej, od góry do dołu).
1. zdjęcie - Luminancja (względna)
Drugie zdjęcie - http://www.w3.org/TR/AERT#color-contrast
Trzecie zdjęcie - model kolorów HSP
4-ci obraz - WCAG 2.0 SC 1.4.3 względem luminancji i współczynnik kontrastu formuła (patrz @ Synchro za odpowiedź tutaj )
Wzór można czasem dostrzec na 1. i 2. zdjęciu w zależności od liczby kolorów w jednym rzędzie. Nigdy nie zauważyłem żadnego wzoru na zdjęciu z trzeciego lub czwartego algorytmu.
Gdybym musiał wybrać, wybrałbym algorytm numer 3, ponieważ jest on znacznie łatwiejszy do wdrożenia i jest o około 33% szybszy niż czwarty.
źródło
^2
Isqrt
zawarte w trzeciej formule są szybszym sposobem aproksymacji liniowego RGB z nieliniowego RGB zamiast^2.2
i^(1/2.2)
byłoby to bardziej poprawne. Niestety stosowanie nieliniowych danych zamiast liniowych jest niezwykle powszechne.Poniżej znajduje się jedyny PRAWIDŁOWY algorytm służący do konwersji obrazów sRGB używanych w przeglądarkach itp. Do skali szarości.
Przed obliczeniem iloczynu wewnętrznego konieczne jest zastosowanie odwrotności funkcji gamma dla przestrzeni kolorów. Następnie zastosujesz funkcję gamma do obniżonej wartości. Brak włączenia funkcji gamma może spowodować błędy do 20%.
W przypadku typowych urządzeń komputerowych przestrzeń kolorów to sRGB. Właściwe liczby dla sRGB to ok. 0,21, 0,72, 0,07. Gamma dla sRGB jest funkcją złożoną, która aproksymuje potęgowanie o 1 / (2.2). Oto cała sprawa w C ++.
źródło
Odpowiedź „zaakceptowana” jest nieprawidłowa i niekompletna
Jedynymi prawidłowymi odpowiedziami są odpowiedzi @ jive-dadson i @EddingtonsMonkey oraz wsparcie @ nils-pipenbrinck . Pozostałe odpowiedzi (w tym zaakceptowane) zawierają linki lub źródła, które są błędne, nieistotne, nieaktualne lub uszkodzone.
Krótko:
Poniżej znajduje się poprawna i pełna odpowiedź:
Ponieważ ten wątek pojawia się wysoko w wyszukiwarkach, dodaję tę odpowiedź, aby wyjaśnić różne nieporozumienia na ten temat.
Jasność jest atrybutem percepcyjnym, nie ma bezpośredniej miary.
Postrzegana jasność jest mierzona za pomocą niektórych modeli wizyjnych, takich jak CIELAB, tutaj L * (Lstar) jest miarą jasności percepcyjnej i jest nieliniowa w celu przybliżenia nieliniowej krzywej odpowiedzi na widzenie.
Luminancja jest liniową miarą światła, ważoną spektralnie dla normalnego widzenia, ale nieskorygowaną dla nieliniowego postrzegania jasności.
Luma ( liczba pierwsza Y ) to zakodowany gamma, ważony sygnał wykorzystywany w niektórych kodowaniach wideo. Nie należy go mylić z luminancją liniową.
Krzywa gamma lub transferowa (TRC) jest krzywą często podobną do krzywej percepcyjnej i jest powszechnie stosowana do danych obrazu w celu przechowywania lub nadawania w celu zmniejszenia postrzeganego szumu i / lub poprawy wykorzystania danych (i powiązanych przyczyn).
Aby określić postrzeganą jasność , najpierw przekonwertuj wartości obrazu R´G´B´ zakodowane gamma na liniową luminancję (
L
lubY
), a następnie na nieliniową jasność postrzeganą (L*
)ABY ZNALEŹĆ LUMINANCJĘ:
... Ponieważ podobno gdzieś się zgubił ...
Krok pierwszy:
Konwertuj wszystkie 8-bitowe wartości całkowite sRGB na dziesiętne 0,0-1,0
Krok drugi:
Przekształć RGB zakodowany w gamma na wartość liniową. Na przykład sRGB (standard komputerowy) wymaga krzywej mocy około V ^ 2,2, chociaż „dokładna” transformacja to:
Gdzie V´ to zakodowany gamma kanał R, G lub B sRGB.
Pseudo kod:
Krok trzeci:
Aby znaleźć Luminancję (Y), zastosuj standardowe współczynniki dla sRGB:
Pseudokod używający powyższych funkcji:
ABY ZNALEŹĆ OCZYWISTĄ LEKKOŚĆ:
Krok czwarty:
Weź luminancję Y z góry i przekształć w L *
Pseudo kod:
L * to wartość od 0 (czarna) do 100 (biała), gdzie 50 to percepcyjna „środkowa szarość”. L * = 50 to odpowiednik Y = 18,4, czyli innymi słowy 18% szara karta, reprezentująca środek ekspozycji fotograficznej (strefa V Ansela Adamsa).
Bibliografia:
IEC 61966-2-1:1999 Standard
Wikipedia sRGB
Wikipedia CIELAB
Wikipedia CIEXYZ
Charles Poynton's Gamma FAQ
źródło
Luma=rgb2gray(RGB);LAB=rgb2lab(RGB);LAB(:,:,2:3)=0;PerceptualGray=lab2rgb(LAB);
L*a*b*
nie uwzględnia szeregu atrybutów psychofizycznych. Efekt Helmholtza-Kohlrauscha jest jeden, ale jest wiele innych. CIELAB w żadnym wypadku nie jest „pełnym” modelem oceny obrazu. W moim poście starałem się jak najlepiej opisać podstawowe pojęcia, nie wchodząc w bardzo głębokie szczegóły. Model Hunt, modele Fairchilda i inne wykonują bardziej kompletną robotę, ale są również znacznie bardziej złożone.Znalazłem ten kod (napisany w języku C #), który świetnie sobie radzi z obliczaniem „jasności” koloru. W tym scenariuszu kod próbuje ustalić, czy należy nałożyć biały lub czarny tekst na kolor.
źródło
Co ciekawe, ta formuła dla RGB => HSV po prostu używa v = MAX3 (r, g, b). Innymi słowy, możesz użyć maksimum (r, g, b) jako V w HSV.
Sprawdziłem i na stronie 575 Hearn & Baker tak też obliczają „Wartość”.
źródło
Zamiast zgubić się wśród losowego wyboru formuł wspomnianych tutaj, sugeruję wybrać formułę zalecaną przez standardy W3C.
Oto prosta, ale dokładna implementacja PHP formuł względnego luminancji i kontrastu WCAG 2.0 SC 1.4.3 . Tworzy wartości, które są odpowiednie do oceny wskaźników wymaganych do zgodności z WCAG, jak na tej stronie , i jako takie są odpowiednie i odpowiednie dla dowolnej aplikacji internetowej. Przeniesienie na inne języki jest banalne.
źródło
Aby dodać to, co powiedzieli inni:
Wszystkie te równania działają trochę dobrze w praktyce, ale jeśli chcesz być bardzo precyzyjny, musisz najpierw przekonwertować kolor na liniową przestrzeń kolorów (zastosować odwrotną gamma obrazu), zrobić średnią wagową kolorów podstawowych i - jeśli chcesz wyświetl kolor - zabierz luminancję z powrotem do gamma monitora.
Różnica luminancji między zapalaniem gamma a robieniem właściwej gamma wynosi do 20% w ciemnych szarościach.
źródło
Rozwiązałem podobne zadanie dzisiaj w javascript. Ustawiłem tę
getPerceivedLightness(rgb)
funkcję dla koloru HEX RGB. Zajmuje się efektem Helmholtza-Kohlrauscha za pomocą formuły Fairchilda i Perrotty do korekcji luminancji.źródło
Przestrzeń kolorów HSV powinna załatwić sprawę, zobacz artykuł w Wikipedii, w zależności od języka, w którym pracujesz, możesz uzyskać konwersję biblioteki.
H to odcień, który jest wartością liczbową koloru (tj. Czerwony, zielony ...)
S to nasycenie koloru, tzn. Jak „intensywne” jest
V to „jasność” koloru.
źródło
Wartość luminancji RGB = 0,3 R + 0,59 G + 0,11 B
http://www.scantips.com/lumin.html
Myślę, że przestrzeń kolorów RGB jest percepcyjnie nierównomierna w odniesieniu do odległości euklidesowej L2. Jednolite przestrzenie obejmują CIE LAB i LUV.
źródło
Formuła odwrotnej gamma autorstwa Jive'a Dadsona musi zostać usunięta w połowie dostosowania, gdy zostanie zaimplementowana w JavaScript, tzn. Zwrot z funkcji gam_sRGB musi być zwrócony int (v * 255); nie zwraca int (v * 255 + .5); Połowa korekty zaokrągla w górę, co może powodować, że wartość jest zbyt wysoka na R = G = B, tj. Triada koloru szarego. Konwersja skali szarości na triadzie R = G = B powinna dawać wartość równą R; to jeden dowód na to, że formuła jest poprawna. Zobacz Nine Shades of Greyscale dla formuły w akcji (bez korekty do połowy).
źródło
Zastanawiam się, jak określono te współczynniki rgb. Zrobiłem eksperyment i skończyłem z następującymi:
Bliskie, ale oczywiście różne od dawno ustalonych współczynników ITU. Zastanawiam się, czy współczynniki te mogą być różne dla każdego obserwatora, ponieważ wszyscy możemy mieć różną liczbę stożków i prętów na siatkówce w naszych oczach, a zwłaszcza stosunek między różnymi rodzajami stożków może się różnić.
Na przykład:
ITU BT.709:
ITU BT.601:
Zrobiłem test, szybko przesuwając mały szary pasek na jaskrawym czerwonym, jasnozielonym i jasnoniebieskim tle, i dostosowując szary, aż połączy się w jak największym stopniu. Powtórzyłem również ten test z innymi odcieniami. Powtórzyłem test na różnych wyświetlaczach, nawet na stałym współczynniku gamma 3,0, ale dla mnie wszystko wygląda tak samo. Co więcej, współczynniki ITU są dosłownie złe dla moich oczu.
I tak, prawdopodobnie mam normalne widzenie kolorów.
źródło
Oto trochę kodu C, który powinien poprawnie obliczyć postrzeganą luminancję.
źródło
Proszę zdefiniować jasność. Jeśli szukasz koloru zbliżonego do białego, możesz użyć odległości euklidesowej od (255, 255, 255)
źródło
„V” HSV jest prawdopodobnie tym, czego szukasz. MATLAB ma funkcję rgb2hsv, a cytowany wcześniej artykuł w Wikipedii jest pełen pseudokodu. Jeśli konwersja RGB2HSV nie jest możliwa, mniej dokładnym modelem byłaby wersja obrazu w skali szarości.
źródło
Ten link wyjaśnia wszystko dogłębnie, w tym dlaczego te stałe mnożnika istnieją przed wartościami R, G i B.
Edycja: Zawiera również wyjaśnienie jednej z odpowiedzi tutaj (0,299 * R + 0,587 * G + 0,114 * B)
źródło
Aby określić jasność koloru za pomocą R, przekształcam kolor systemu RGB na kolor systemu HSV.
W moim skrypcie używam wcześniej kodu systemowego HEX z innego powodu, ale możesz także zacząć od kodu systemowego RGB za pomocą
rgb2hsv {grDevices}
. Dokumentacja jest tutaj .Oto ta część mojego kodu:
źródło
Dla jasności muszą to być formuły korzystające z pierwiastka kwadratowego
sqrt(coefficient * (colour_value^2))
nie
sqrt((coefficient * colour_value))^2
Dowodem na to jest konwersja triady R = G = B na skalę szarości R. Będzie to prawdą tylko wtedy, gdy wyrównasz wartość koloru, a nie wartość razy razy współczynnik koloru. Zobacz dziewięć odcieni szarości
źródło