Прозрачный PNG стал чёрным: как согласовать фон изображения перед инференсом

В браузере карточка товара выглядит привычно: белая кружка на белом фоне. После загрузки в сервис классификации вокруг неё появляется чёрный прямоугольник, и качество падает. Изображение было прозрачным PNG. Цвет под прозрачными пикселями не обязан совпадать с тем фоном, который показывал браузер. Удаление альфа-канала без согласованного наложения меняет вход модели.

Альфа-канал описывает непрозрачность пикселя. В полностью прозрачной области RGB может содержать чёрный, белый или оставшиеся данные редактора. Просмотрщик смешивает эти значения со своим фоном. Если сервис просто оставляет первые три канала, он получает другую картинку. Поэтому фон должен быть частью подготовки данных, одинаковой при обучении и инференсе.

Сначала воспроизведём изменение пикселей

Создадим полупрозрачный красный пиксель и полностью прозрачный чёрный. В Pillow обычное convert("RGB") убирает альфа-канал, но не подставляет желаемый белый фон. Для наложения используем Image.alpha_composite: оба изображения предварительно приводятся к RGBA и имеют одинаковый размер.

from PIL import Image
image = Image.new("RGBA", (2, 1))
image.putdata([(255, 0, 0, 128), (0, 0, 0, 0)])
dropped = image.convert("RGB")
white = Image.new("RGBA", image.size, (255, 255, 255, 255))
served = Image.alpha_composite(white, image).convert("RGB")
a = list(dropped.getdata())
b = list(served.getdata())
print("drop_alpha", a)
print("white_background", b)
assert a == [(255, 0, 0), (0, 0, 0)]
assert b == [(255, 127, 127), (255, 255, 255)]
assert served.mode == "RGB"

После удаления канала второй пиксель стал чёрным. После наложения он белый, а полупрозрачный красный смешался с белым и стал светлее. Это уже разные входные значения, даже до resize и нормализации. На фотографии с большим прозрачным полем разница затронет значительную часть площади. Она может изменить и цветовой фон, и вид границы товара.

Выберем фон по задаче, а не по расширению файла

Если обучающие фотографии снимались на белом фоне, белое наложение — естественная исходная гипотеза. Но она требует проверки на реальных примерах: у тёмных объектов светлая кайма после вырезания может мешать распознаванию. Сравните несколько вариантов фона на отложенной выборке прозрачных изображений и посмотрите ошибки по типам товара. Общая метрика на JPEG может скрыть проблему маленькой группы PNG.

Если прозрачность несёт полезную информацию о форме, можно хранить маску отдельно либо обучать модель с нужным числом каналов. Нельзя просто передать RGBA в модель, ожидающую RGB: число каналов является частью контракта. Также проверьте порядок цветов в используемых библиотеках. Ошибка RGB/BGR независима от альфа-канала и способна остаться после правильного наложения.

Где закрепить правило

Оформите одну функцию загрузки изображения и используйте её в подготовке обучающих данных, локальной оценке и API. В контракт запишите режим цвета, фон, обработку прозрачности, resize и диапазон значений тензора. Версия этого правила должна выпускаться вместе с моделью. Так замена декодера или перенос в другой сервис не изменит картинку незаметно.

Для палитрового PNG прозрачность может храниться иначе, чем явный четвёртый канал. Приведение к RGBA до наложения даёт общий путь обработки. При этом настройка цветового профиля — отдельный вопрос: если точность цвета критична, согласуйте преобразование профилей и проверяйте его на эталонных изображениях. Простое изменение числа каналов такую задачу не решает.

Добавьте в тесты непрозрачный RGB, полностью прозрачный PNG, полупрозрачный край и палитровый файл. Для каждого сохраняйте ожидаемый размер, режим и несколько контрольных пикселей. Полезен также визуальный контактный лист до и после подготовки: числовые проверки обнаруживают нарушение контракта, а человек замечает кайму и потерянные детали. Сравнивайте именно изображения, которые доходят до нормализации модели.

После выпуска отмечайте долю изображений с прозрачностью и частоту ошибок декодирования. Если поставщик начал отдавать новый тип PNG, отдельный срез покажет изменение раньше общего показателя качества. Фон перестаёт быть случайным свойством просмотрщика и становится воспроизводимой частью сервиса.

При проверке кеша подготовленных картинок включите версию фона в ключ. Иначе после смены правила часть запросов продолжит получать старые RGB-изображения из кеша. Это создаст смесь двух подготовок внутри одного релиза и затруднит сравнение метрик.

В курсе вы готовите и проверяете CV-датасеты, обучаете модели и собираете API со скриптом инференса. Следующий практический шаг — перенести согласованную подготовку изображения в воспроизводимый сервис и оценить её влияние на ошибки детекции, сегментации или классификации. Откройте программу платного курса «Computer Vision Engineer: от детекции и Doc-AI до продакшна».

Продолжить на практике

  • Computer Vision Engineer: от детекции и Doc-AI до продакшна ↗

    Практический курс по Computer Vision. Соберёте продакшн-сервис: датасет → обучение (YOLO/RT-DETR, SAM), трекинг, OCR/Doc-AI, веб-приложение (UI+API) и мониторинг. Экспорт в ONNX/TensorRT/OpenVINO, батчинг/квантование под CPU/GPU. Плюс профессиональные блоки: mAP/IoU/Dice и калибровка доверия, QA разметки и аугментации, p95/стоимость, дрейф данных и алерты, guardrails (NMS/правила), A/B-тесты, Triton/gRPC/FastAPI.