Кадр в памяти: форма, размер и BGR → RGB на Python
После чтения изображение занимает в памяти другой объём, чем файл на диске, а порядок каналов зависит от декодера. Реализуйте отчёт по кадру и преобразование каналов по условию; вход приходит готовыми списками, NumPy и OpenCV не нужны.
Откройте программу платного курса Computer Vision Engineer, чтобы продолжить практику с данными, моделями и CV-сервисом.
Отчёт по прочитанному кадру
Первое, что делают с кадром после cv2.imread, — смотрят, что именно прочиталось: какой формы массив, сколько он занимает в памяти и в том ли порядке лежат каналы. Соберём эту проверку в одну функцию, чтобы дальше не считать руками каждый раз.
Задание
Напишите функцию frame_report(frame, dtype, file_bytes). Она получает кадр, название типа чисел и размер исходного файла на диске в байтах, а возвращает словарь с шестью ключами:
height,width— высота и ширина кадра в пикселях;channels— число каналов;memory_kib— сколько килобайт занимает кадр в памяти, округлить до одного знака после запятой (1 КБ = 1024 байта);ratio— во сколько раз память больше файла на диске, округлить до одного знака;rgb— тот же кадр с каналами в порядке RGB.
Кадр приходит вложенными списками, повторяя форму массива из cv2.imread: внешний список — строки пикселей сверху вниз, внутри каждой строки — пиксели слева направо, а каждый цветной пиксель — три числа в порядке BGR.
Тип чисел приходит строкой: "uint8" — по одному байту на число, "float32" — по четыре. Это и есть разница между кадром сразу после чтения и им же после нормализации, и в объёме памяти она видна вчетверо.
Одноканальный кадр устроен иначе: у снимка в градациях серого нет третьего уровня вложенности, строка состоит просто из чисел. Тогда channels равен 1, а в rgb возвращается тот же кадр без изменений — переставлять там нечего.
Пример
# кадр 480 на 640, каждый пиксель [b, g, r], файл на диске 60 КБ
report = frame_report(frame, "uint8", 61440)
report["height"] # 480
report["width"] # 640
report["channels"] # 3
report["memory_kib"] # 900.0
report["ratio"] # 15.0
frame_report([[[24, 108, 144]]], "uint8", 1024)["rgb"] # [[[144, 108, 24]]]
Примечание
На платформе нет ни numpy, ни opencv, поэтому кадр и тип чисел приходят обычными объектами Python. У себя в окружении те же величины берутся из массива напрямую: форма — из frame.shape, тип — из frame.dtype, объём в памяти — из frame.nbytes.
Весь код держите внутри функции: на проверку отправляется только она, и вспомогательные переменные, объявленные рядом на верхнем уровне, до неё не доедут. Исходный кадр менять не нужно — rgb собирается отдельным списком.
Вызывать функцию самостоятельно не нужно — проверка запустит её сама на нескольких кадрах разной формы и разного типа чисел.
Что проверяется
Код проверок скрыт, так что вот полный список того, что в них разбирается:
- формат ответа: словарь с ключами
height,width,channels,memory_kib,ratioиrgb; - кадр 480 на 640 из примера: форма, объём в памяти и отношение к размеру файла;
- порядок каналов на одном пикселе;
- одноканальный кадр:
channelsравен 1, аrgbвозвращается без изменений; - цветной кадр целиком: каждый пиксель развёрнут из BGR в RGB;
- исходный кадр при этом не меняется;
float32вместоuint8— та же форма, вчетверо больше памяти;- прямоугольный кадр: высота и ширина не меняются местами.
Без регистрации. Гостевая проверка не сохраняет прогресс. Для сохранения перейдите к уроку.
Отправьте решение, чтобы увидеть результаты тестов.
