RGB
RGB builds every screen color from three lights. Red, green and blue. Each pixel stores one brightness per light, and the triple sets the exact shade you see.
Why Does This Exist?
Screens emit light and sensors count it, and both are built around three primaries because human eyes have three cone types. RGB is therefore the native tongue of cameras, files and displays: every photo starts as RGB numbers and every screen ends by glowing RGB triples.
That convenience is also the trap. RGB tangles color with brightness, so the same object gets a different triple under different light, which is why vision pipelines convert to spaces like HSV or LAB before deciding anything. Read the parent overview in color spaces for when to leave RGB behind.
Think of It Like This
Three flashlights on one wall
Shine a red, a green and a blue flashlight at the same spot on a white wall. Red plus green paints yellow, all three at full blast make white, and dimming one flashlight shifts the mixture toward the other two.
Each flashlight dimmer is one RGB channel, for off and for full. A pixel is just three dimmer settings written down.
The analogy stops here: flashlights add light linearly, but screens apply a gamma curve, so the middle dimmer setting looks darker than half brightness.
How It Actually Works
RGB is an additive model over three channels . At 8 bits each, every channel is an integer from to , so one pixel is a point in a cube with about million possible addresses (). Adding lights moves toward white: is pure red, is yellow, is white, is black.
, and here mean stored intensities, not wavelengths. A sensor counts photons through red, green and blue filters, and a screen drives red, green and blue subpixels. Both sides agree on the channel idea but differ on exact shades, which is why calibrated work names a standard.
sRGB is the RGB you actually meet
Raw channel values are gamma-encoded under the sRGB standard: the stored number is roughly the physical brightness raised to , so mid-gray emits only about a fifth of full white light, not half. Do math on physical light (blending, simulating illumination) only after linearizing; feed networks the stored values as-is, since that is what they were trained on.
Worked example: mixing yellow and clipping white
Red light plus green light gives : yellow, with the blue channel untouched at . Adding is per-channel, and screens clip instead of wrapping: on one channel stores , never . That clipping is why overexposed skies go flat white rather than cycling to odd colors.
Code
def add_channel(a, b): return min(a + b, 255) # screens clip; they never wrap around
print(add_channel(200, 100))print((255, 0, 0)[0] + 0, (0, 255, 0)[1] + 0, 0) # red + green = yellow# -> 255# -> (255, 255, 0)Watch Out For
OpenCV loads BGR while your model expects RGB
OpenCV reads images as blue-green-red from old hardware habits; cameras, files, PyTorch and Matplotlib speak RGB. Feeding BGR straight into an RGB-trained network scrambles every color cue with zero errors raised. Convert once at load time and assert a known red patch reads high in channel 0.
uint8 addition wraps where light should clip
Adding two uint8 arrays in NumPy wraps modulo 256, so becomes , a dark glitch no screen would ever show. Cast to a wider type, add, clip to , then cast back.
The Quick Version
- RGB stores one intensity per red, green and blue channel: a point in a cube of 16.8 million addresses.
- Mixing is additive per channel, so R plus G reads as yellow and all three full read as white.
- Stored values are gamma-encoded (sRGB), so mid-gray emits far less than half the light.
- OpenCV speaks BGR while models expect RGB; convert once at load time.
- Channel arithmetic must clip at 255, because uint8 addition wraps to dark glitches.