Az RGB aritmetika
(RGB color mixing)Ez a cikk az RGB színkeverés: RGB1 + RGB2 kiszámítását írja le.
A legfontosabb eltérés az additív és szubtraktív színkeverésben, hogy addtívnál: Fény + Sötétség = Fény, mert a sötétség nem létezik, mivel az csak a fény hiánya.
A szubtraktív színkeverésben: Fénylő + Sötét = Sötétedés.
Csak érdekességként jegyzem meg, hogy ehhez a kétfajta színkeveréshez két metafizikai gondolkodást is csatolhatnánk.
Mindkét színkeverésre érvényes, hogy azonos színek esetén:
A + A = A , tehát nem 2A mint az algebrában.
(Megjegyzendő viszont, hogy a pigmentek keverése esetében fontos a higítás és a felvitt szín vastagsága is, melyek szintén meghatározzák a végső színt. A festékek keverése más modellt is igényel, mivel itt a sárga RGB(255,255,0) és a kék RGB(0,0,255) keveréke fehéret adna, viszont a pigmentek keverésében ez zöldet eredményez.)
Fényerő az emberi szem érzékenysége szerint:
Luminance = 0.2126×R + 0.7152×G + 0.0722×B
HSV modellben a világosság: V = max(R, G, B)
Definiálunk még egy fogalmat, az átlagos RGB fényerőt: L = (r + g + b) / 3
Két szín esetén L = (r1 + g1 + b1 + r2 + g2 + b2) / 6
A szubtraktív színkeverésre ervényes L(RGB1, RGB2) ≥ L(RGB), tehát két szín összekeveréséből keletkező színben sohasem növekedhet az átlagos fényerő.
Felmerül a kérdés, hogy az RGB milyen színkeverés? Additív vagy szubtraktív? Ennek megértése nagyon fontos. Az RGB model additív színkeverésre épül, de ha két színt RGB1, RGB2 össze akarunk keverni (pixelek szintjén), akkor mindkét elv érvényesülhet egyszerre is, ugyanis a sötétséggel is dolgoznunk kell, mert ez már egy teljesen más dolog, mint maga az RGB modell. (Tehát RGB szinkeverésen két különböző dolgot érthetünk.) Ennek okán, ha a monitor színeit keverjük, pl. ha a pirosat és a feketét a pixelek szintjén összegkeverjük, akkor sötét pirosat látunk, nem tiszta pirosat. Más esetben pedig RGB1 + RGB2 additív módon viselkedik. Mivel mindkét keverési elv érvényesülhet a RGB1 + RGB2 végeredményében, ezért minden jóval bonyolultabb lesz, amikor meg akarjuk határozni, hogy milyen színt fogunk látni, ha két színt összekeverünk.
Színkeverés
Színkeverés modellezése úgy történik, hogy a két színt pixelenként váltakoztatva rajzolunk ki, ahogy az lejjebb látható és kipróbálható.
A helyes színhez a weboldal nagyítását 100% vagy 200% kell állítani másként a kép színét a web elmossa. A két színt legjobban úgy tudjuk összehasonlítani, ha távolabról nézzük, vagy kicsit hunyorítunk a szemünkkel.
Ahogy tudjuk pl. RGB(255,0,0) + RGB(0,0,0) piros és a fekete keveredése más szint eredményez, mint RGB(255,0,0) tiszta pirosat, ami azt jelenti, hogy a végső színt szubtraktív keverésben látjuk nem additívben, illetve helyesen mindkettőben egyszerre.
Ahhoz, hogy csak additív keverésben lássuk a végső színt, az itt létrehozott képet a monitor egészére kéne kitenni és egy sötét szobában a monitor elé egy fekete paírlapot téve, a parírlapon megjelenő színt kéne megnéznünk.
Viszont a monitoron a két szín RGB(255,0,0) + RGB(0, 0, 0) keverése kb. RGB(180, 0, 0) színt eredményez, mintha egy szín volna.
≈
mix RGB by CIE XYZ
A színskála
Az emberi szem igen érdekes módon érzékeli a három alapszín változását. Számunkra a színek változása a színskála.
Ez a színskála (a megkülönböztethető színek lineáris rendje) nagyon érdekes módon jön létre.
Ami érdekes ebben, hogy a színpárok színeit figyeljük, ahol a szinpárból az egyik alapszín mindig maximális értéken van.
A többi szín valójában csak a fényerősség, illetve a fehér - fekete viszonyt adja ezekből a színpárokból.
Filozófiai szempontból is érdekes, hogy valójában mindig egy párost, illetve 2 alapszínt figyelünk, illetve a kettő arányát figyeljük (annak ellenére, hogy 3 alpszínünk van),
és még azt, hogy ezen páros hol helyezkednek el a fény és a sötétség között.
I. A megfelelő alapszínek felcserélhetősége a színkeverésben
Két szín összeadásában felcserelhetők a megfelelő komponensek, illetve a megfelelő alapszínek:
RGB(a, b, c) + RGB(x, y, z) = RGB(x, b, c) + RGB(a, y, z)
II. Két alapszín keveredése
Az előbbiekben említettem, hogy RGB1 + RGB2 színkeverés végső színének kiszámolásához figyelembe kell venni az additív és a szubtraktív jelleget is, illetve azt,
hogy milyen mértékben kell az egyiket és a másikat alkalmazni.
Logikusan feltételezhetjük, ha a két szín (a1, a2) melyeknek összegét ki akarjuk számolni, egymástól nagyon eltérőek,
akkor fokozottabb mértékben kell figyelembe venni a keverésnél az additív hatást.
Ezt könnyen le lehet ellenőrizni mérési eredményekkel. Valójában nem olyan fontos a pontos összefüggés, elegendő számunkra egy közelitő érték,
bár valószinűleg ennek pontos összefüggését a jövőben biztosan meghatározzák majd.
A számításokhoz bevezetjük az additívitás mértékét (közelítő összefüggéssel), Adt:
Adt = 0.2220×Delta − 0.0875×Avg + 0.0235×Max ahol : Delta = ABS(a1 - a2) Avg = (a1 + a2) / 2 Max = MAX(a1, a2)
Így két szín keveredését, a = a1 + a2, így számolhatjuk ki:
a ≈ Adt(a1, a2) + Avg(a1, a2) ennek az eredménynek természetesen a1, a2 intervallumban kell lennie.
Példák: 1. RGB(255, 255, 0) + RGB(255, 0, 0) RGB(a1, b1, 0) + RGB(a2, b2, 0) = RGB(a, b, 0) Adt = 0.2220×Delta − 0.0875×Avg + 0.0235×Max Adt(a1,a2) = 0.2220*0 − 0.0875*255 + 0.0235*255 ≤ 0 a = Adt + Avg = 255 Adt(b1,b2) = 0.2220*255 − 0.0875*127.5 + 0.0235*255 = 51.44625 b = 51.44625 + 127.5 ≈ 179 RGB(255, 255, 0) + RGB(255, 0, 0) ≈ RGB(255, 179, 0) A sárga és a piros keveréke narancssárga színt eredményez, de nem RGB(255, 128, 0), hanem kb. ≈ RGB(255, 179, 0). 2. RGB(210, 128, 0) + RGB(200, 0, 0) RGB(a1, b1, 0) + RGB(a2, b2, 0) = RGB(a ,b ,0) Adt = 0.2220×Delta − 0.0875×Avg + 0.0235×Max Adt(a1,a2) = 0,2220*10 − 0,0875*205 + 0,0235*210 = -10.7825 Adt = 0 a = Adt + Avg = 205 Adt(b1,b2) = 0.2220*128−0.0875*64+0.0235*128 = 25.824 b = 25.824 + 64 = 90 RGB(210, 128, 0) + RGB(200, 0, 0) ≈ RGB(205, 90, 0)
Ezt a módszert használhatjuk mindhárom alapszín esetén is, ami engem teljesen meglepett.
3. RGB(255, 255, 0) + RGB(0, 255, 255) Avg(127.5, 255, 127.5) Adt(51.5, 0, 51.5) RGB(179, 255, 179) RGB(255, 255, 0) + RGB(0, 255, 255) ≈ RGB(179, 255, 179) 4. RGB(220, 50, 100) + RGB(180, 90, 200) Avg(200, 70, 150) Adt = 0.2220×Delta − 0.0875×Avg + 0.0235×Max Adt(r1, r2) = 0,2220*40 − 0,0875*200 + 0,0235*220 = -3.45 Adt(g1, g2) = 0,2220*40 − 0,0875*70 + 0,0235*90 = 4,87 Adt(b1, b2) = 0,2220*100 − 0,0875*150 + 0,0235*200 = 13,775 Adt(0, 4.87, 13.775) RGB(200, 75, 164) RGB(220, 50, 100) + RGB(180, 90, 200) ≈ RGB(200, 75, 164)
Ahogy láthatjuk a képletnek van bizonyos hibája, ami reálisan 3 körül mozog (RMSE),
de a meréseim, illetve saját szín érzékelésem és monitorom, sem mondhatók pontosaknak, tehát ezt el lehet fogadni.
Viszont ahogy észrevettem minden alapszín egy kicsit másként viselkedik, illetve az emberi szem másként látja.
Ez jól látható elsősorban a piros és a zöld színkeverékek összehasonlítása esetén, mert a piros színkeverékek nagyobb hibát mutatnak, mint a zöld esetében.
Ami azt jelenti, hogy minden színre kicsit más képlet volna jó. Mindennek ellenére, szerintem egész jó megközelítésnek tekinthető ez a módszer.
Viszont ezzel kapcsolatban a CIE XYZ modell, nagyon jó eredményeket ad: https://en.wikipedia.org/wiki/CIE_1931_color_space
1. RGB → CIE XYZ Konverzió: https://www.easyrgb.com/en/math.php
function befor(c) { let var_c = c / 255; if ( var_c > 0.04045 ) { var_c = Math.pow(( var_c + 0.055 ) / 1.055 , 2.4); } else { var_c = var_c / 12.92; } return var_c; } r1 = befor( rgb1[0] ); g1 = befor( rgb1[1] ); b1 = befor( rgb1[2] ); r2 = befor( rgb2[0] ); g2 = befor( rgb2[1] ); b2 = befor( rgb2[2] ); x1 = 0.4124 * r1 + 0.3576 * g1 + 0.1805 * b1; y1 = 0.2126 * r1 + 0.7152 * g1 + 0.0722 * b1; z1 = 0.0193 * r1 + 0.1192 * g1 + 0.9505 * b1; x2 = 0.4124 * r2 + 0.3576 * g2 + 0.1805 * b2; y2 = 0.2126 * r2 + 0.7152 * g2 + 0.0722 * b2; z2 = 0.0193 * r2 + 0.1192 * g2 + 0.9505 * b2;
2. Két szín keverése CIE XYZ-ben: Miután mindkét színt átalakítottuk XYZ koordinátákra, a keverés lépése következik. A színkeverés legegyszerűbb módja a színcsatornák átlagolása. Ez azt jelenti, hogy az egyes X, Y és Z értékeket külön-külön átlagoljuk. Ez a lépés az additív színkeverés alapja, ami azt jelenti, hogy mindkét szín intenzitásait (fényerő és színtartalom) összeadjuk, majd átlagoljuk őket, hogy egy új, kevert színt kapjunk. Amikor két színt keverünk össze, a kapott szín x és y értéke azon az egyenes szakaszon fekszik, amely összeköti őket a CIE xy színdiagramján.
x = (x1 + x2) / 2; y = (y1 + y2) / 2; z = (z1 + z2) / 2;
3. CIE XYZ → RGB Konverzió: https://www.easyrgb.com/en/math.php
Miután megkaptuk a kevert XYZ értékeket, vissza kell konvertálni őket RGB formátumba.
function after(c) { let var_c=0.0; if (c > 0.0031308) { var_c = 1.055 * Math.pow(c, 1 / 2.4) - 0.055; } else { var_c = 12.92 * c; } return var_c*255; } r = 3.2406 * x - 1.5372 * y - 0.4986 * z; g = -0.9689 * x + 1.8758 * y + 0.0415 * z; b = 0.0557 * x - 0.2040 * y + 1.0570 * z; r = after( r ); g = after( g ); b = after( b );
4. A kiszámolt RGB értékek kerekítése [0,255] intervallumra
r = Math.trunc(0.05+r); g = Math.trunc(0.05+g); b = Math.trunc(0.05+b); r = Math.max(0, Math.min(255, r) ); g = Math.max(0, Math.min(255, g) ); b = Math.max(0, Math.min(255, b) );
2025-02-11, (c) Tungli János, Párkány