Images as Arrays and Grayscale Conversion
Intuition
A colour image is a grid of pixels, each with red, green and blue intensities. Our eyes are most sensitive to green and least to blue, so a perceptually sensible grey level weights green most.
Precise explanation
- Colour image: array
(H, W, 3), usuallyuint8in 0..255 (RGB order here; OpenCV loads BGR). - Grayscale:
(H, W). - ITU-R BT.601 luma weights (used by OpenCV's
cvtColorRGB→GRAY): . With broadcasting:img @ np.array([0.299, 0.587, 0.114]). - Arithmetic on
uint8wraps around (250 + 10 = 4). Convert to float first; convert back with rounding and clipping to [0, 255].
Worked example
Pure red (255, 0, 0) → 76.245 → 76; pure green → 149.685 → 150; white → 255.
Common mistakes
- Averaging channels equally (looks wrong: blue appears too bright).
- BGR/RGB confusion with OpenCV.
astype(np.uint8)without rounding/clipping (truncation and wrap-around).
Why this matters
Many classical algorithms (edges, thresholding) work on single-channel images; dtype handling prevents silent overflow bugs.
References
- OpenCV Tutorials (OpenCV 4.13.0) — OpenCV team (
S023) - Scientific Python Lectures — Scientific Python developers (
S006)