
В прошлых статьях я разбирал основы апскейлинга дома и сходил с ума, вырезая закадровый смех из «Скуби-Ду». Тот опыт привёл меня к выводу: существующие инструменты, будь то плагины вроде NeatVideo или комбайны типа Topaz Video AI — это «чёрные ящики». У них ограниченный набор настроек, и они часто пасуют перед специфическими задачами старой анимации.
В этот раз я пошёл от обратного. Сразу снижу градус ожиданий: это любительский эксперимент. Мы сильно ограничены в мощности GPU (в наличии только RTX 4060 Ti), из-за чего натренировать реально точную, тяжелую нейросеть-универсала возможности нет.
Поэтому вместо гонки за идеальными метриками я сосредоточился на «неудобных» проблемах. Я написал симулятор уничтожения плёнки, чтобы научить легкую модель понимать физику конкретных дефектов: от сдвига эмульсии до химических ожогов и растяжения плёнки кинопроектором.
Спойлер: на это ушло 2 месяца и 2 миллиона итераций. Получилась не «волшебная кнопка», а набор узкоспециализированных инструментов.
Техническое вступление: Что под капотом?
Прежде чем переходить к истории обучения, давайте определимся с инструментом.

Архитектура: Real-ESRGAN Compact.
Если вы качали готовые модели для апскейла, вы могли видеть файлы с пометкой realesrgan-x4plus. Это тяжёлые модели на базе RRDBNet. Я же выбрал их младшего брата.

Почему Compact?
Скорость. Это легковесная архитектура. Она работает в разы быстрее стандартных трансформеров (SwinIR) или тяжёлых ResNet-ов.
Конфигурация
48nf16nc: Это означает, что у модели 48 фильтров и 16 свёрточных слоёв. Для сравнения: «большие» модели обычно имеют 64 фильтра и 23 блока. В моём случае я ограничен видеокартой RTX 4060 Ti 16 Гб.
В чём главный прикол?
Обычно ESRGAN используют для апскейла (увеличения разрешения в 2 или 4 раза). Нейросеть берёт 1 пиксель и придумывает вокруг него 3 новых.
Я использую «апскейл» 1 к 1.

Я не прошу модель увеличивать картинку. Я скармливаю ей кадр 1080p и прошу вернуть те же 1080p.
В чём суть: Вместо того, чтобы тратить ресурсы на придумывание новых пикселей для увеличения, вся мощь генеративной сети уходит на перерисовку текущих пикселей. В этот момент классический апскейлер превращается в продвинутый денойзер: он не «сглаживает» шум (как простые математические денойзеры), он заново генерирует участок изображения, опираясь на то, что имел на входе.
Важно сразу оговориться: это сугубо энтузиастский, «гаражный» эксперимент. Мы тут не тренируем конкурента SORA 3 на кластере из GB200. В моём распоряжении лишь домашняя RTX 4060 Ti.
Это накладывает жесточайшие ограничения. Натренировать на таком железе действительно глубокую, тяжелую и математически точную нейросеть (которая могла бы тягаться с топами по метрикам) физически невозможно — на это ушли бы годы. Поэтому я не гнался за идеальным восстановлением каждого пикселя, а сделал ставку на скорость и решение специфических проблем, которые игнорируют другие.
Зачем? Разве нет готовых решений?
Безусловно, они есть. Но существующие денойзеры (как классические математические, так и современные нейросетевые) имеют фундаментальные недостатки при работе с классическим целлулоидом (плёнкой).
1. NeatVideo — мощный комбайн, но требует от пользователя огромнейшего опыта. Не все дефекты убитой временем плёнки можно описать его алгоритмами. Чуть перекрутил настройки — получил «мыло» на фонах. Недокрутил — шум ушёл, но Джерри на заднем плане оброс шипами-артефактами по 20 пикселей во все стороны.

Так и сам интерфейс сложный. Я потратил на приобретение навыков уровня «полупрофессионал» больше 30 часов практики, без учёта времени обработки видео после.

2. DRUNet — отличная нейросеть, но она работает условно «математически», не понимая контекста. По моим наблюдениям, у неё есть только понятия «контур» и «фон».
Она может идеально вычистить мелкий цифровой шум, но оставить эффект «пыли». Это крупные артефакты в 5–10 пикселей — наследие «копий с копий» (позитивов и интерпозитивов). При каждом тиражировании фильма для кинотеатров зерно на плёнке неизбежно множилось.
Она не знает, что делать с горизонтальными линиями от растяжения плёнки.
На MPEG-артефактах она часто частично ломается.

Для справки: SCUNet
Это мощная гибридная архитектура (смесь трансформера и CNN), которая работает точнее DRUNet. Но это «тяжеловес»: SCUNet в два раза медленнее DRUNet, тогда как моя модель — в два раза быстрее. Из-за такой пропасти в скорости и сложности запуска он просто выпадает из нашей лиги.
3. Archivist (Мой проект)
Я не пытался создать «убийцу NeatVideo» или «убийцу DRUNet». Мой инструмент — это скорее «Mini-NeatVideo++».
Mini, потому что он проигрывает в точности на сложных паттернах. Из-за архитектуры
48nf16ncу модели ограниченное поле зрения. Условно, если персонаж носит рубашку в мелкую клетку «светло-тёмным на тёмном» с тонкими линиями (2–3 пикселя), она может принять узор за царапины или особый паттерн зерна и удалить их. NeatVideo работает по иным принципам и с такой проблемой вряд ли бы столкнулся.++, потому что он имеет встроенные «плагины» для того, с чем не справляются другие: удаление линий растяжения, High ISO зёрна от сканеров и крупного мусора.
Но в большинстве случаев он выигрывает за счёт обученного распознавания паттернов. Утрированно: там, где обычный математический денойзер видит «резкий контраст» (и либо размывает его, принимая за шум, либо оставляет, принимая за деталь), нейросеть «узнаёт» знакомый ей характер зерна или царапины и реконструирует этот участок, фактически перерисовывая его заново на основе выученных весов.
Акт 1: Ловушка «Идеального» Датасета
Моя первая попытка была в 2024 году, тогда обучение началось с классической ошибки. Я взял 1024 пары кадров, где в качестве эталона (GT) использовал результат прогона через NeatVideo.
Проблема «Гало» и цвета
NeatVideo часто немного меняет геометрию объектов и цветовую палитру картинки. А также я сам, не особенно вникая в процесс, пытался «улучшить» выходной результат, хотя даже не умел правильно вытащить кадры из видео, из-за чего зерно выглядит, как jpeg, и отличается от настоящего.

Модель, обучаясь на этом, внезапно начала рисовать ореолы. А настройки l1_gt_usm: true (повышение резкости) в конфиге, которые должны были «бесплатно» помогать, лишь усилили эту неочевидную тягу к созданию ореолов.

В итоге модель научилась делать изображение чрезмерно резким, добавляя светящиеся контуры и геометрические искажения. Принцип «мусор на входе — мусор на выходе» сработал безотказно.

Решение: Смена парадигмы (Ломать — не строить)
Я упёрся в тупик: найти идеальную пару «Грязный кадр — Чистый кадр» в реальности невозможно. Любая обработка NeatVideo или DRUNet оставляет следы, и нейросеть учится их повторять.
Я решил посмотреть проблему в профиль: вместо попыток очистить убитую плёнку для датасета, нужно брать качественные Blu-ray исходники и искусственно их состаривать.

Почему нам плевать на геометрию?
Чтобы получить «Эталон» (Ground Truth), я прогонял Blu-ray кадры через агрессивную связку DRUNet + Bandage Smooth + sudo-RealESRGAN. Это вычищает всё до блеска, но иногда немного «плавит» геометрию и контуры.

В контексте реставрации это был бы брак. Но для обучения нейросети — это не баг, а фича (в теории).
Мы берём этот «поплывший», но стерильный кадр как Эталон.
На него же накладываем зерно и грязь для Входа.
Нейросеть видит, что геометрия на Входе и Эталоне одинаково слегка кривая в деталях. Единственная разница между ними — шум. Поэтому сеть игнорирует искажения форм и фокусируется исключительно на задаче: «как превратить эту кашу из зёрен обратно в чистую картинку».
Так у меня появились идеальные «чистые» данные. Осталось самое сложное — научиться правдоподобно их портить.
Акт 2: Project Degrader — Симулятор износа
Главная проблема стандартных датасетов — использование простого Гауссова шума (утрированно). Но реальная плёнка стареет иначе.
Эволюция хаоса
Сначала я базово наложил самый обычный цветной шум. Модель научилась идеально чистить «цифру», но пасовала перед реальной плёнкой. Пришлось заняться анализом сканов:
На глубоком чёрном зерна почти нет (нужна маска по яркости).
Зерно — это не пиксели, а «хлопья» определённых оттенков.
Слабое звено (Синий): В нормальном состоянии на плёнке всегда больше всего шумит синий канал — так устроены светочувствительные слои.

С ИИ процесс пошёл ещё глубже: пытаясь заставить модель «понимать» дефекты, я сам узнавал, как именно деградирует старая плёнка. Например, выяснилось, что к естественному зерну синего канала со временем добавляется «химический шум» в красном. Это происходит из-за того, что голубой краситель — циановый слой, отвечающий за красный канал — в архивах выцветает и разрушается быстрее остальных.
В общем, тема очень и очень глубокая, а не банальный «шум из точек».
Так, скрипт усложнялся, количество параметров перевалило за 20. Стало слишком сложно настраивать это чисто в виде тек��та, и я написал Project Degrader — GUI-приложение на Python (PyQt6) для процедурной генерации устаревания плёнки.

P. S.: Свечку не держал, специалистом по плёнке не являюсь, так что в алгоритмах наверняка есть неверные выводы и предубеждения в какой-то степени. Я чистый энтузиаст.
Чему модель научилась благодаря этому софту:
Кризис: Геометрическая деформация изображения, имитирующая растяжение плёнки проектором.
Умные царапины: Кривые Безье и «волоски», а не прямые линии.
Химия: Пятна, выцветание, высокий ISO шум.
MPEG-деблокинг: Очистка от квадратов сжатия и цифрового «звона» вокруг линий.
Прочее...: Устранение Mpeg-блочности, поиск контуров под мусором...

# Фрагмент конвейера генерации
pipeline_steps = [
TextureTrapStep(...), # Ловушки текстур
CreaseStep(...), # Геометрические складки
EmulsionShiftStep(...), # Сдвиг каналов RGB
DebrisStep(...), # Мусор
ScratchesStep(...), # Царапины
EmulsionDegradationStep(...) # Хим. деградация
# ...
]
Акт 3: Битва с «мылом» и нейросетевая «ипохондрия»
Имея качественные данные, я запустил обучение. И снова провал.
Попытка №1 (Мыло):
Произошёл сговор внутри нейросети. Генератор (рисующая часть) понял: «Если я просто размою картинку, математическая ошибка будет ниже, чем если я попытаюсь нарисовать деталь и промахнусь на пару пикселей». Дискриминатор (проверяющая часть) согласился. В итоге вместо реставрации я получил идеально размытые пятна.

Попытка №2 (Инвертированное мыло):
Я сменил Дискриминатор на VGGStyle и выкрутил GAN Loss. Контуры стали резкими, но текстуры внутри объектов исчезли. Плюс пошли галлюцинации (кирпичная кладка на траве). Более того, обучение шло в 2–3 раза дольше, чем при использовании стандартного UNetDiscriminatorSN.
Вывод: Откат обратно.
Попытка №104324 («Ипохондрия»):
В сгенерированном датасете было слишком много мелких пятен (вероятность 40–80%). Модель получила «профессиональную деформацию» и начала лечить всё, что «совпадало по паттерну».

Попытка №##### (Буллинг):
Дискриминатор забулил Генератор. Дискриминатор абсурдно легко отличал фальшивку от оригинала. В итоге Генератор перестал получать полезную информацию: любое его улучшение меняло уверенность «судьи» лишь на ничтожные 0,0001% и возвращалось обратно на следующем же шаге Дискриминатора. Чтобы такой казус не произошёл вновь, потребовалось снизить максимальное значение «уверенности» Дискриминатора до 90%, чтобы его штрафовали за «рубание топором».
Решение:
Перебалансировка датасета по принципу MoE (Mixture of Experts) — архитектуры с набором экспертов.
10% — простые случаи.
30% — средние.
60% — сложные.
Мы ограничили возможность нейросети «схитрить». Ей приходится одновременно решать задачу по очистке шума и по сохранению детализации. На простых примерах мы требуем идеальной точности, а на сложных — «хоть как-то найти детали, но постарайся без галлюцинаций». Ей предстоял сложный поиск золотой середины.
Акт 4: Финал и специализация моделей
К 450 000 итерации стало очевидно: из-за ограничений моей архитектуры (Compact) сделать одну «супер-модель», которая и детали сохранит, и мусор уберет — не получится. Ей просто не хватает «мозгов» (параметров), чтобы удержать в голове всё сразу.
Поэтому я перестал мучить нейросеть попытками стать универсальной и разбил её на узкие специальности:

И именно здесь кроется главная ценность проекта. Базовые «чистильщики» (Soft/Medium) работают неплохо, но в контексте других решений — проседают. Настоящая цель, ради которой всё затевалось — это модели AntiLines, RGB и отчасти Rough. Аналогов нейросетевых денойзеров или апскейлеров, которые бы в принципе решали именно эти специфические проблемы плёнки, в открытом доступе я не встречал.
1. AntiLines (457 тыс. итераций)
Специализация: Горизонтальные линии (растяжение плёнки), разрывы, царапины.
Это модель-уборщик. Я взял базовую обученную модель и провёл файн-тюнинг на специфическом датасете: вероятность появления геометрических дефектов (Creases) и разрывов была выкручена на 80%. Удивительно, но для достижения результата хватило буквально 6-7 тысяч итераций дообучения. Теперь она видит линии и удаляет их там, где другие денойзеры видят полезный сигнал, сохраняют их или (что хуже) превращают в «кирпичную кладку».

2. Rough (493 тыс. итераций)
Специализация: Убитые исходники, High ISO шум, «вязкая» грязь.
Обучалась преимущественно на профиле Heavy (самые сложные деградации), а также во всех остальных профилях были включены вероятности выпадения всевозможных пыли и мусора. Она агрессивна. Она ищет пыль и пятна, стараясь устранить их любыми способами.

3. Medium (478 тыс. итераций)
Специализация: Золотая середина.
Баланс между чисткой и сохранением оригинальной текстуры. Лучший вариант для первого прогона, чтобы понять, с чем мы имеем дело. Обучалась на сбалансированном миксе дефектов.

4. Soft (453 тыс. итераций)
Специализация: Минимальное вмешательство.
Модель для почти чистых исходников, где нужно убрать лишь лёгкое плёночное зерно. Она лучше справляется с многослойным шумом и не создаёт «эффект пыли», характерный для DRUNet.
Нюанс: Модель использует лёгкую архитектуру 48nf16nc (48 фильтров и 16 каналов). В совсем простых сценариях она может проигрывать чистому DRUNet, который математически точнее на микро-уровне и видит больше контекста, поэтому и меньше лажает.

5. RGB (193 тыс. итераций)
Специализация: Плёночный шум с высокой степенью разложения эмульсии всех слоёв.
Модель обучалась отдельно от остальных с нуля. Использовалась более «творчески свободная» конфигурация обучения (выше вес GAN loss), а в генераторе датасета был везде включён экстремальный режим цветовых искажений. Спасает картинку от шума, возникающего при плохом сканировании или сжатии. Фокусируется на цветовых каналах.

Главный инсайт (Гибридный пайплайн)
Мой денойзер — это структурный инструмент. Абстрактно говоря: он видит разницу между мусором и глазом персонажа, но математически он не идеален (может оставить микро-дрожание пикселей). DRUNet же, наоборот, отлично «вылизывает» плоские поверхности, убирая цифровой шум.
Лучший результат даёт комбинация:
Archivist (AntiLines или Medium) — убирает мусор, линии, крупные ошмётки, сдвиги эмульсии, чинит MPEG.
DRUNet — убирает остаточный микро-шум и стабилизирует картинку, чтобы она не трясл��сь.
Итоги
В сухом остатке: 2 месяца работы, 2 миллиона итераций обучения.
Получился инструмент, который занимает свою нишу между «умными» алгоритмами и чистой математикой. Он балансирует между ручной реставрационной деятельностью и арифметической точностью удаления шума. Это как писать чёрной гелевой ручкой, пытаясь имитировать карандаш: похоже, стильно, но не карандаш, он «другой». Зато он спасает то, что другие считают безнадёжным.
Всё выложено в Open Source. И модели, и код генератора датасетов.
Ссылки:
© 2025 ООО «МТ ФИНАНС»
Комментарии (25)

Ilya_JOATMON
27.12.2025 14:09Здорово. А не думали о темпоральном денойзере? Очень часто просто статика или панорамирование идет.
Для целлулоидной анимации, как мне кажется, надо искать путь отделять фон от нарисованного на целлулоиде и применять разные фильтры к ним соответственно. Так как рисованное на целлулоиде это линии и примерно однотонные заливки, но фон это полноценные картины с мелкими деталями и полутонами. И фильтр который отлично очистит шума целлулоидную часть одновременно уничтожит мелкие детали и переходы фона. Что собственно на сравнениях и видно. А если фон отделить то его можно стакнуть чем в разы уменьшить случайный шум пленки.

Realife Автор
27.12.2025 14:09А не думали о темпоральном денойзере?
Да, но обучение такой модели - это кратно сложнее, нежели то, с чем я уже был знаком (ESRGAN compact). И я бы хотел всё же, чтобы мой эксперимент получил некоторую распространенность, и ESRGAN для этого отлично подходит, так как абсолютное большинство GUI умеет работать с данной архитектурой
Для целлулоидной анимации, как мне кажется, надо искать путь отделять фон от нарисованного на целлулоиде и применять разные фильтры к ним соответственно
Если я правильно понял, то вы говорите об оригинальных фреймах, с которых снимали плёнку, но это скорее абстрактное рассуждение, ибо все они либо лежат в архивах под семью печатями, либо уже давно утеряны/сгорели/испортились. Например, у MGM раза 2 с лишним горели архивы».

Ilya_JOATMON
27.12.2025 14:09Я не говорю про оригинал, это естественно невозможно. Я говорю про слои - слой фона и слой анимации. И соответственно про разные фильтры к этим слоям.

Realife Автор
27.12.2025 14:09Тогда речь скорее идёт о диффузионных апскейлерах и кластер-апскейлерах, как, например, Starlight от Topaz. На словах - это, конечно, интересно, но на деле для этого нужен просто огромный R&D отдел плюс копаться в разработках китайцев на arXiv

Ilya_JOATMON
27.12.2025 14:09На ebay и yahoo аукционах можно купить набор анимационного кадра фон + один или несколько cell, от каких-либо фильмов или сериалов. Не думали себе такой купить? Чтобы иметь представленние о том как оно в ОРИГИНАЛЕ выглядит.

ky0
27.12.2025 14:09Проделанная работа вызывает уважение, но получившиеся "векторные мультики, сделанные в Флэше" лично мне нравятся меньше, чем зернистые исходники. Как будто что-то важное пропадает.

Realife Автор
27.12.2025 14:09Не могу не согласиться, что косяк с мощностью нейросети есть, но если посмотреть с другой стороны - после проделанной работы осталась программа для генерации датасетов, которая не зависит от текущих ограничений, так что может когда-нибудь в другой раз, но у меня выйдет обучить что-то на уровне больших решений) А так самые главные результаты, которые для меня здесь есть - Antilines и RGB модели
Хоть я и не являюсь сторонником зерна на видео, но объективно детализация страдает по нынешним результатам

VBDUnit
27.12.2025 14:09Имхо тут лучше разделить техническую и художественную составляющие.
С одной стороны, если фильм требуется масштабировать (в любую сторону) и/или пережимать, то делать это лучше без шумов, чтобы «зернистая ламповость» не превратилась в рябящее мыло. Потому что шумы алгоритмы сжатия видео не любят, особенно когда битрейт низкий (а в интернете он очень низкий). С другой стороны, желательно иметь возможность сохранить тёплошумную ламповость, хотя бы в каком то виде.
Можно действовать так:
Берём оригинальное видео А
Удаляем шум — получаем видео без шума Б
Попиксельно вычитаем из видео А видео Б — получаем видео с самим шумом В
Видео с шумом В дополнительно обрабатываем так, чтобы там полностью перестало проглядываться оригинальное видео Б — границы, тени, силуэты и прочее. Сделать это можно, например, с помощью двумерного преобразования Фурье и удалением низкочастотной составляющей + ещё парой допобработок.
Теперь, у нас есть:
Оригинальное видео с шумом А
Видео без шума Б
Видео только с самим шумом В
И если нам надо, например, отмасштабировать видео (апскейл/даунскейл), то мы:
Масштабируем видео без шума Б (нейросеткой/бикубически/билинейно/ланцош — не важно)
Накладываем на него шум В без масштабирования (!), при необходимости увеличиваем/уменьшаем интенсивность шума В — по вкусу. Если новый размер кадра меньше оригинала — обрезаем, если больше — дозаполняем каким‑нибудь дублированием с маскированием стыков. Вообще можно тупо выделять спектр шума и потом его заново генерить по этому спектру в требуемом разрешении, но это не подойдёт для всяких ворсинок и прочих аналоговых штук
Кодируем
Если при этом битрейт требуется очень низкий, то нужно предварительно поиграться со спектром шума на видео В и понизить амплитуду (по пространству и/или по времени), которые алгоритм сжатия превращает в мыло, а остальное оставить.
Если масштабирование не требуется — всё равно, мы можем что‑нибудь сделать с шумом, чтобы при сжатии кодеком он не мылился. Для совсем энтузиастов можно хранить их — видео Б и шум В — отдельно, и сводить непосредственно при просмотре.
Разумеется, все промежуточные результаты мы сохраняем либо в формат со сжатием без потерь (ProRes какой‑нибудь), либо в виде сиквенсов. Можно и fp32, если место есть.
То есть мы отдельно протаскиваем через обработку отдельно картинку без шума, отдельно сам шум, и работаем с ними независимо, чтобы сохранить максимум художественной составляющей в конце по вкусу. Нравится шум — будет шум, нравится без шума — будет без шума, хочется чего‑то промежуточного — тоже можно.

denismartyanov
27.12.2025 14:09Зерно ещё и к тому же прячет артефакты кодирования - вот на AntiLines и последнем скриншотах хороши видны блоки на ровных текстурах (да ещё и они сами выглядят как пластилин).
Это скорее выглядит как один из этапов обработки, потому что по хорошему в таких случаях нужно после удаления имеет смысл накладывать свой шум, поменьше и возможно менее динамичный - который будет лучше жаться, иметь меньше артефактов, чем изначальный, скрывать артефакты самой картинки и спасать от "выглядит как флеш и пластилин". Как правило при обработке старых источников так и делали в каком-нибудь ависинте - сначала шумодав (не настолько сильный, впрочем, как правило), потом дитеринг и добавление шума.

Zikfrid3000
27.12.2025 14:09Заканчивался 2025 год и все уже практически забыли про AviSynth, в том числе pythone'ированный., не говоря уже о doom9. org с кучей скриптов для линейной и не линейной обработки видео...

Hycklare
27.12.2025 14:09Прекрасно, вот ради таких статей я и прихожу на Хабр. Особенно интересно видеть реализацию на сверточных сетях, сейчас всё на трансформерах делается, а тут как-то привычнее.
Keks650
Выглядит отлично!)
Решил тут детям показать Утиные истории, всё что находится достаточно паршивого качества, при просмотре на 50" телике, либо черезчур контрастный апскейл, о котором вы говорите.
Тот результат, что вы показали - выглядит очень прилично. Как долго обрабатывается скажем 30 минутная серия?
Realife Автор
Зависит от вашей видеокарты) По теме можете у меня почитать эти 2 материала: О выборе ПО и о том как вкатится в домашний апскейлинг
Ilya_JOATMON
Утиные истории не имеют, к сожалению, хд трансфера с пленки. Все что есть это попытки почистить и апскельнуть двд исходник, не лучшего качества. Результат соответствующий - мусор на входе - мусор на выходе. Лучше Chip&Dale, для них есть ХД трансфер (исключая одну серию вроде)