Восстановление изображений
Восстановление изображений принимает искажённое изображение и возвращает чистое. LibreYOLO предоставляет его как задачу restore, которая охватывает шумоподавление, устранение размытия и суперразрешение за единым контрактом вывода: на входе одно RGB-изображение, на выходе одно RGB-изображение.
Определение
Задача restore отображает одно изображение в другое. Шумоподавление,
устранение размытия и суперразрешение — здесь одна и та же задача, потому что у
них общий контракт: модель принимает RGB-изображение и возвращает
RGB-изображение, а деградация, которую модель учили устранять, — свойство
чекпойнта, а не API.
Предсказание заполняет result.restored — полезную нагрузку RestoredImage с
массивом RGB (H, W, 3) типа uint8. .array возвращает его как NumPy, а
.save(path) записывает его на диск. result.restore_scale хранит коэффициент
увеличения, который несёт выходной холст; для чекпойнта, сохраняющего
разрешение, он равен 1. result.boxes остаётся пустым, поэтому conf, iou
и max_det принимаются ради совместимости сигнатуры, но ни на что не влияют, а
save=True записывает восстановленное изображение напрямую, а не аннотированное
фото.
Модели
Задачу restore обслуживают три семейства, разделённые по деградации, которую
они устраняют.
NAFNet отвечает за шумоподавление и остаётся единственным семейством restore, которое LibreYOLO умеет обучать. Его архитектура заменяет нелинейные активации в блоке UNet поэлементным умножением, а опубликованный чекпойнт обучен на реальном шуме SIDD. Разрешение выхода совпадает со входным.
Real-ESRGAN — практичный вариант для увеличения разрешения: три чекпойнта, обученные на синтетических деградациях, а не только на бикубическом уменьшении, с масштабами 4x, 2x и меньшим, более быстрым генератором 4x, рассчитанным на меньшую задержку.
SwinIR увеличивает разрешение в 4 раза с бэкбоном Swin Transformer, в трёх размерах, охватывающих официальный облегчённый генератор и два генератора для реальных изображений.
Предсказание
Веса скачиваются с Hugging Face при первом запуске и кэшируются локально.
from libreyolo import LibreYOLO, SAMPLE_IMAGE # Компактный генератор 4x; tile ограничивает пик памяти на большом источнике.model = LibreYOLO("LibreRealESRGANx4t-restore.pt")result = model(SAMPLE_IMAGE, tile=512, tile_pad=10) result.restored.save("upscaled.png")print(result.restored.array.shape) # в 4 раза больше входа по каждой осиfrom libreyolo import LibreYOLO, SAMPLE_IMAGE # Обучена на реальном шуме SIDD; размер выхода совпадает со входным.model = LibreYOLO("LibreNAFNetl-restore-sidd.pt")result = model(SAMPLE_IMAGE) result.restored.save("denoised.png")print(result.restore_scale) # 1: этот чекпойнт не увеличивает разрешениеВосстановление работает в собственном разрешении исходного изображения, а не на
фиксированном холсте сети, и дополняет его только до кратности коэффициенту
понижения разрешения сети, поэтому и время, и память растут вместе с числом
пикселей входа. tile разбивает прямой проход на перекрывающиеся тайлы и
сглаживает стыки между ними, а tile_pad — это поля вокруг каждого тайла,
которые потом обрезаются обратно; оба — именованные аргументы Python. Про
источники, стриминг и обработку результата смотрите
предсказание.
Формат датасета
Восстановление сопоставляет каждому искажённому входному изображению чистое целевое изображение ровно того же разрешения; пара определяется по имени файла без расширения.
dataset/
data.yaml
inputs/
train/photo.jpg
val/photo.jpg
targets/
train/photo.jpg
val/photo.jpgpath: dataset
train: inputs/train
val: inputs/val
input_dir: inputs
target_dir: targets
degradation: denoise
dataset: MyDataset
nc: 1
names: {0: image}nc и names — заглушки схемы; модель restore возвращает Results.restored, а
не детекции. degradation и dataset — необязательные метки происхождения.
target_stem_suffix рассчитан на датасеты, где чистое изображение названо
иначе, чем его искажённая пара. Валидация сохраняет исходное разрешение и
дополняет ровно настолько, чтобы собрать батч, поэтому метрики считаются на
исходном холсте. Полный контракт описан в
форматах датасетов.
Обучение
NAFNet — единственное семейство restore с реализацией обучения.
Real-ESRGAN.train() и SwinIR.train() оба выбрасывают NotImplementedError:
эти чекпойнты получены GAN-обучением поверх синтетических пайплайнов деградации,
и обучающий цикл restore для парных данных запустился бы, не воспроизводя этот
рецепт.
from libreyolo import LibreYOLO model = LibreYOLO("LibreNAFNetl-restore-sidd.pt")model.train(data="my-dataset.yaml", epochs=100, imgsz=256, batch=16, lr0=1e-3)from libreyolo import LibreYOLO model = LibreYOLO("LibreNAFNetl-restore-sidd.pt") # degradation и dataset записываются в сохранённый чекпойнт для# отслеживания происхождения; в обучении они не участвуют.model.train( data="my-dataset.yaml", epochs=100, degradation="denoise", dataset="MyDataset",)Обучающий цикл берёт из входного и целевого изображений согласованные кропы, поэтому обе стороны остаются выровненными. Про датасеты, обучение на нескольких GPU и логгеры смотрите обучение, а про умолчания этого семейства и пулинг, который оно применяет на инференсе и отключает во время обучения, — страницу NAFNet.
Валидация
val() сравнивает восстановленное изображение с чистой целью, в RGB, на исходном
холсте, без обрезки границ и без изменения размера.
from libreyolo import LibreYOLO model = LibreYOLO("LibreNAFNetl-restore-sidd.pt") # val() возвращает обычный dict, а не объект.metrics = model.val(data="my-dataset.yaml") print(metrics["metrics/PSNR"]) # fitnessprint(metrics["metrics/SSIM"])metrics/PSNR — пиковое отношение сигнала к шуму в децибелах, и это же значение
служит fitness, числом, по которому выбирается лучший чекпойнт.
metrics/SSIM — структурное сходство в [0, 1], посчитанное с гауссовым окном
11x11 при сигме 1.5 и усреднённое по трём цветовым каналам. Для обеих метрик
больше — лучше.
Экспорт
Экспортированная модель restore загружается обратно через LibreYOLO() по
суффиксу файла, поэтому файл .onnx или .engine ведёт себя как чекпойнт и
возвращает тот же Results, где restored несёт выходное изображение.
from libreyolo import LibreYOLO model = LibreYOLO("LibreNAFNetl-restore-sidd.pt") # imgsz фиксируется в графе, поэтому передавайте тот размер, который# ваше развёртывание действительно подаёт модели.model.export(format="onnx", imgsz=256)from libreyolo import LibreYOLO, SAMPLE_IMAGE # Фабрика выбирает загрузчик по суффиксу файла, поэтому экспортированный# артефакт грузится как обычный чекпойнт и возвращает тот же Results.model = LibreYOLO("LibreNAFNetl-restore-sidd.onnx")result = model(SAMPLE_IMAGE) result.restored.save("denoised.png")Экспорт restore фиксирует пространственное разрешение в графе, поэтому
передавайте тот imgsz, который ваше развёртывание действительно будет подавать
модели. Для NAFNet этот размер должен делиться на коэффициент понижения
разрешения сети, и при dynamic=True динамическим остаётся только измерение
батча. Для Real-ESRGAN и SwinIR, если imgsz не указан, берётся небольшой
внутренний размер патча, а не ваше рабочее разрешение. Поддержка по
форматам описана на странице каждой модели и в
полной матрице экспорта. В разделе
экспорт перечислены аргументы, которые принимает каждый формат.