Реалізація AI-збільшення роздільної здатності зображень (Super Resolution / Upscale)

Проектуємо та впроваджуємо системи штучного інтелекту: від прототипу до production-ready рішення. Наша команда поєднує експертизу в машинному навчанні, дата-інжинірингу та MLOps, щоб AI працював не в лабораторії, а в реальному бізнесі.
Показано 1 з 1Усі 1566 послуг
Реалізація AI-збільшення роздільної здатності зображень (Super Resolution / Upscale)
Простий
~2-3 дні
Часті запитання

Напрямки AI-розробки

Етапи розробки AI-рішення

Останні роботи

  • image_website-b2b-advance_0.webp
    Розробка сайту компанії B2B ADVANCE
    1288
  • image_web-applications_feedme_466_0.webp
    Розробка веб-додатків для компанії FEEDME
    1198
  • image_websites_belfingroup_462_0.webp
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    902
  • image_ecommerce_furnoro_435_0.webp
    Розробка інтернет магазину для компанії FURNORO
    1122
  • image_logo-advance_0.webp
    Розробка логотипу компанії B2B Advance
    589
  • image_crm_enviok_479_0.webp
    Розробка веб-додатків для компанії Enviok
    859

ШІ Super-Resolution — апскейл зображень

Бікубічна інтерполяція дає 4x апскейл із розмиттям. ШІ 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 (все зображення) при 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 Швидко Застаріла
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 pass
    # (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 denoise (nf_denoise з BasicSR)

Часові рамки

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