Изображение как данные: пиксели, каналы и градации серого
Главная мысль раздела: для машины картинка — не «изображение», а двумерная таблица чисел.
Пиксель (pixel) — наименьший элемент растрового изображения; для него хранится яркость (в сером) или набор значений каналов (в цвете).
Картинка — это матрица
Чёрно-белое (точнее, в градациях серого) изображение — это сетка пикселей, где каждое число задаёт яркость. Обычно яркость кодируют одним байтом: 0 — чёрный, 255 — белый, между ними — оттенки серого. Соберём из чисел маленькую «картинку» 5×5 и нарисуем её символами: яркие пиксели как #, тёмные как ..
img = [
[0, 0, 0, 0, 0],
[0, 255, 255, 255, 0],
[0, 255, 0, 255, 0],
[0, 255, 255, 255, 0],
[0, 0, 0, 0, 0],
]
for row in img:
line = "".join("#" if p > 128 else "." for p in row)
print(line)
print()
print("Размер:", len(img), "x", len(img[0]))
print("Пиксель [2][2]:", img[2][2])
Вывод:
..... .###. .#.#. .###. ..... Размер: 5 x 5 Пиксель [2][2]: 0
Видно квадратную «рамку» из ярких пикселей с тёмным центром. Это и есть изображение для компьютера: индексы [y][x] — координаты, значение — яркость. Никакой магии — обычная вложенная таблица.
Цвет: три канала RGB
Цветное изображение хранит на каждый пиксель не одно число, а три — интенсивности красного (R), зелёного (G) и синего (B). Картинка превращается в три наложенных матрицы — каналы. Смешивая R, G, B, получают любой цвет: (255,0,0) — красный, (0,255,0) — зелёный, (255,255,255) — белый, (0,0,0) — чёрный.
| RGB | Цвет |
| (255, 0, 0) | красный |
| (0, 255, 0) | зелёный |
| (0, 0, 255) | синий |
| (255, 255, 0) | жёлтый (R+G) |
| (0, 0, 0) | чёрный |
Так фото 1000×1000 в цвете — это 1000×1000×3 = 3 миллиона чисел. Для нейросети это вход тензора формы (высота, ширина, каналы).
Из цвета в серый
Часто цвет не нужен — форма объекта важнее окраски. Тогда три канала сворачивают в один по формуле яркости, которая учитывает, что глаз чувствительнее к зелёному и слабее к синему:
pixels = [
(255, 0, 0),
( 0, 255, 0),
( 0, 0, 255),
(255, 255, 255),
( 0, 0, 0),
(128, 128, 128),
]
for (r, g, b) in pixels:
gray = round(0.299 * r + 0.587 * g + 0.114 * b)
print(f"RGB({r:3},{g:3},{b:3}) -> {gray}")
Вывод:
RGB(255, 0, 0) -> 76 RGB( 0,255, 0) -> 150 RGB( 0, 0,255) -> 29 RGB(255,255,255) -> 255 RGB( 0, 0, 0) -> 0 RGB(128,128,128) -> 128
Обратите внимание: чисто зелёный даёт яркость 150, а чисто синий — всего 29. Коэффициенты 0.299 / 0.587 / 0.114 подобраны под восприятие человеческого глаза (стандарт luma). Простое среднее (r+g+b)/3 тоже работает, но выглядит «неправильно»: синее небо кажется слишком светлым.
Итог
- Изображение для машины — матрица чисел, индексы
[y][x]— координаты пикселя. - Серое изображение — одна матрица яркостей
0..255. - Цветное — три канала R, G, B; форма входа нейросети
(H, W, 3). - Перевод в серый — взвешенная сумма каналов под чувствительность глаза.