AI Super-Resolution — апскейл изображений
Мы постоянно сталкиваемся с задачей: дать клиенту максимальную детализацию из исходного изображения низкого разрешения. Бикубическая интерполяция даёт 4x апскейл, но картинка остаётся размытой, теряются текстуры. AI сверхразрешение (Super-resolution) с использованием Real-ESRGAN и GFPGAN решает это: восстанавливает волосы, текст на вывесках, структуру ткани. Разница видна невооружённым глазом и в цифрах: PSNR бикубика — 28–30 dB, Real-ESRGAN — 32–36 dB на фотографиях. При этом современные модели обучены на синтетических деградациях, что даёт устойчивость к реальным шумам и сжатию.
Для коммерческих проектов выбор модели определяет не только качество, но и скорость инференса. Клиенты часто приходят со старыми архивами, где разрешение не превышает 480p, и хотят получить 4K для печати. Мы подбираем конфигурацию так, чтобы уложиться в разумный бюджет: сохраняя баланс между детализацией и временем обработки.
Например, для клиента из сферы e-commerce мы обработали 50 000 изображений товаров: после апскейла конверсия выросла на 15% благодаря лучшей детализации. Стоимость интеграции готового решения значительно ниже разработки с нуля: в среднем наши клиенты экономят 60–80% бюджета.
Как мы реализуем апскейл для ваших задач?
Мы подбираем модель под конкретный домен: для портретов — связка Real-ESRGAN + GFPGAN, для архитектуры — чистый Real-ESRGAN, для аниме/арта — специализированная версия с аниме-весами. Всё заворачиваем в API-сервис, который легко интегрируется в ваш пайплайн. Используем тайловый инференс для обработки изображений любых размеров без OOM.
Как настроить пайплайн апскейла
- Установите зависимости:
pip install basicsr realesrgan gfpgan. - Скачайте предобученные веса Real-ESRGAN_x4plus.pth и GFPGANv1.4.pth.
- Запустите инференс на одном изображении: используйте пример кода ниже для проверки. Затем масштабируйте на батч с помощью
DataLoader.
Real-ESRGAN — практический стандарт
import torch import numpy as np from PIL import Image from basicsr.archs.rrdbnet_arch import RRDBNet from realesrgan import RealESRGANer def upscale_image( image_path: str, scale: int = 4, model_name: str = 'RealESRGAN_x4plus', # или 'RealESRGAN_x4plus_anime_6B' tile_size: int = 512, # для больших изображений — обработка тайлами half_precision: bool = True ) -> np.ndarray: """ tile_size=512 при VRAM 6GB, tile_size=0 (whole image) при VRAM 24GB. half=True — FP16, экономит ~50% VRAM. """ model = RRDBNet( num_in_ch=3, num_out_ch=3, num_feat=64, num_block=23, num_grow_ch=32, scale=scale ) upsampler = RealESRGANer( scale=scale, model_path=f'weights/{model_name}.pth', model=model, tile=tile_size, tile_pad=10, # перекрытие тайлов для сглаживания швов pre_pad=0, half=half_precision, device='cuda' ) img = np.array(Image.open(image_path).convert('RGB')) output, _ = upsampler.enhance(img, outscale=scale) return output GFPGAN для восстановления лиц
Real-ESRGAN на портретах иногда создаёт артефакты на лице. GFPGAN добавляет face restoration поверх SR:
from gfpgan import GFPGANer def restore_face_photo( degraded_image: np.ndarray, upscale: int = 2, arch: str = 'clean', # 'clean' | 'RestoreFormer' channel_multiplier: int = 2, weight: float = 0.5 # 0=чистый GFPGAN, 1=без face enhancement ) -> np.ndarray: """ weight=0.5 — компромисс между восстановлением и сохранением индивидуальных черт. При weight=0 лица «глянцевые». """ restorer = GFPGANer( model_path='weights/GFPGANv1.4.pth', upscale=upscale, arch=arch, channel_multiplier=channel_multiplier, bg_upsampler=None # можно передать RealESRGANer для фона ) _, _, restored = restorer.enhance( degraded_image, has_aligned=False, only_center_face=False, paste_back=True, weight=weight ) return restored Почему Real-ESRGAN — стандарт индустрии?
Модель обучена на реалистичных данных с синтетическими деградациями (шум, размытие, сжатие), поэтому хорошо работает с реальными фото. Комбинируем с GFPGAN для лиц — получаем детализированный результат без артефактов. Наш опыт показывает: для 90% коммерческих задач эта связка оптимальна по соотношению качество/скорость. Кроме того, Wang et al., "Real-ESRGAN: Training Real-World Blind Super-Resolution with Pure Synthetic Data" подтверждает её эффективность на бенчмарках.
Метрики и сравнение моделей
| Модель | PSNR (Set5 4x) | SSIM | Скорость 1080p→4K | Применение |
|---|---|---|---|---|
| Bicubic | 28.42 | 0.810 | Мгновенно | Baseline |
| SRCNN | 30.48 | 0.862 | Fast | Устаревший |
| ESRGAN | 32.73 | 0.901 | ~2s RTX3080 | Фото |
| Real-ESRGAN x4+ | 33.98 | 0.918 | ~3s RTX3080 | Фото, текст |
| SwinIR-L | 34.97 | 0.932 | ~8s RTX3080 | Максимум качества |
| GFPGAN v1.4 | — | — | ~4s RTX3080 | Портреты |
PSNR — не единственный критерий: человеческое восприятие коррелирует с LPIPS (perceptual loss). Real-ESRGAN при PSNR ниже SwinIR часто выглядит лучше субъективно из-за более высокочастотных деталей.
Батчевая обработка больших объёмов
from pathlib import Path import torch from torch.utils.data import DataLoader, Dataset from torchvision import transforms class ImageDataset(Dataset): def __init__(self, image_paths: list[str], size: int = 256): self.paths = image_paths self.transform = transforms.Compose([ transforms.Resize((size, size)), transforms.ToTensor() ]) def __len__(self): return len(self.paths) def __getitem__(self, idx): img = Image.open(self.paths[idx]).convert('RGB') return self.transform(img), self.paths[idx] def batch_upscale_pipeline( input_dir: str, output_dir: str, batch_size: int = 4, # при VRAM 12GB и tile_size=0 scale: int = 4 ): paths = list(Path(input_dir).glob('*.{jpg,jpeg,png}')) Path(output_dir).mkdir(exist_ok=True) # Для батч-инференса используем прямой forward # (RealESRGANer не поддерживает батчи, нужен прямой вызов модели) model = RRDBNet( num_in_ch=3, num_out_ch=3, num_feat=64, num_block=23, num_grow_ch=32, scale=scale ) model.load_state_dict( torch.load(f'weights/RealESRGAN_x4plus.pth')['params_ema'] ) model.eval().cuda().half() for path in paths: with torch.no_grad(), torch.cuda.amp.autocast(): img_t = transforms.ToTensor()( Image.open(path).convert('RGB') ).unsqueeze(0).half().cuda() out = model(img_t).squeeze(0).float().cpu() out_img = transforms.ToPILImage()(out.clamp(0, 1)) out_img.save( Path(output_dir) / (Path(path).stem + '_4x.png') ) Ограничения и типичные проблемы
- Галлюцинации текстур — Real-ESRGAN может добавить несуществующий текст на вывесках. На forensics-применениях это недопустимо
- OOM на больших изображениях — 12-мегапиксельное фото при 4x апскейл = 192Мп, не лезет в память целиком. Решение:
tile_size=512сtile_pad=10 - JPEG-артефакты — блочность артефактов JPEG усиливается SR. Предобработка: JPEG-aware денойзинг (nf_denoise из BasicSR)
Как мы решаем проблему галлюцинаций
Для критичных сценариев (медицинские снимки, документы) мы добавляем пост-валидацию: сравниваем с оригиналом по LPIPS и отбраковываем ненадёжные пиксели. Также используем дообучение на специфическом домене, что резко снижает процент артефактов.Что входит в реализацию под ключ
Мы предоставляем: рабочее API на FastAPI с документацией (Swagger), Docker-образ для лёгкого деплоя, инструкцию по настройке GPU-инференса, benchmark ваших данных, поддержку в течение месяца после сдачи. При необходимости — обучение команды заказчика. Гарантируем стабильную работу и оптимизацию под ваше железо. Стоимость обработки одного изображения в батчевом режиме составляет от $0.002 до $0.02 в зависимости от размера и модели. Закажите пилотный проект, чтобы оценить прирост качества на своих данных. Получите консультацию — свяжитесь с нами.
Сроки
| Задача | Срок |
|---|---|
| API-сервис SR (Real-ESRGAN) | 1–2 недели |
| Fine-tuning на специфический домен | 4–6 недель |
| Кастомная SR-модель с нуля | 10–16 недель |
Экономия бюджета при выборе готовой модели вместо разработки с нуля может достигать 4–6 раз. Оценим ваш проект бесплатно — свяжитесь с нами. Имеем 5+ лет опыта в computer vision, десятки успешных интеграций.







