Реализация AI-увеличения разрешения изображений (Super Resolution / Upscale)

Проектируем и внедряем системы искусственного интеллекта: от прототипа до production-ready решения. Наша команда объединяет экспертизу в машинном обучении, дата-инжиниринге и MLOps, чтобы AI работал не в лаборатории, а в реальном бизнесе.
Показано 1 из 1 услугВсе 1566 услуг
Реализация AI-увеличения разрешения изображений (Super Resolution / Upscale)
Простая
~2-3 рабочих дня
Часто задаваемые вопросы
Направления AI-разработки
Этапы разработки AI-решения
Последние работы
  • image_website-b2b-advance_0.png
    Разработка сайта компании B2B ADVANCE
    1218
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1161
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    854
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1047
  • image_logo-advance_0.png
    Разработка логотипа компании B2B Advance
    561
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    825

AI Super-Resolution — апскейл изображений

Бикубическая интерполяция даёт 4x апскейл с размытием. AI super-resolution восстанавливает детали: текстуры кожи, текст на вывесках, структуру ткани. Разница видна при сравнении PSNR: бикубик — 28–30 dB, Real-ESRGAN — 32–36 dB на фотографиях.

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

Метрики и сравнение моделей

Модель 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)

Сроки

Задача Срок
API-сервис SR (Real-ESRGAN) 1–2 недели
Fine-tuning на специфический домен 4–6 недель
Кастомная SR-модель с нуля 10–16 недель