Реалізація Inpainting (заповнення областей зображення)

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

Напрямки 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

Розробка AI-інпейнтингу для заповнення областей зображення

Інпейнтинг замінює виділену маскою область зображення новим змістом, органічно вписуючи його в оточуючий контекст. Застосовується для видалення об'єктів, заміни фонів, реставрації, змін елементів дизайну.

diffusers інпейнтинг

from diffusers import StableDiffusionXLInpaintPipeline
from PIL import Image, ImageDraw
import torch
import io
import numpy as np

class InpaintingService:
    def __init__(self):
        self.pipe = StableDiffusionXLInpaintPipeline.from_pretrained(
            "diffusers/stable-diffusion-xl-1.0-inpainting-0.1",
            torch_dtype=torch.float16,
            use_safetensors=True,
            variant="fp16"
        ).to("cuda")

    def inpaint(
        self,
        image_bytes: bytes,
        mask_bytes: bytes,      # білий = замінити, чорний = зберегти
        prompt: str,
        negative_prompt: str = "low quality, blurry, artifacts",
        strength: float = 0.99,
        steps: int = 30,
        guidance_scale: float = 8.0
    ) -> bytes:
        image = Image.open(io.BytesIO(image_bytes)).convert("RGB")
        mask = Image.open(io.BytesIO(mask_bytes)).convert("L")

        # Розміри повинні збігатися і бути кратні 8
        w, h = image.size
        w, h = (w // 8) * 8, (h // 8) * 8
        image = image.resize((w, h))
        mask = mask.resize((w, h))

        result = self.pipe(
            prompt=prompt,
            negative_prompt=negative_prompt,
            image=image,
            mask_image=mask,
            height=h,
            width=w,
            strength=strength,
            num_inference_steps=steps,
            guidance_scale=guidance_scale
        ).images[0]

        buf = io.BytesIO()
        result.save(buf, format="PNG")
        return buf.getvalue()

Автоматичне створення маски

from transformers import pipeline
import numpy as np

class AutoMaskGenerator:
    def __init__(self):
        # SAM (Segment Anything) для точної сегментації
        self.sam = pipeline("mask-generation", model="facebook/sam-vit-huge", device="cuda")

    def mask_by_text(self, image: Image.Image, text_query: str) -> Image.Image:
        """Створюємо маску через CLIP + SAM за текстовим описом"""
        from transformers import CLIPSegProcessor, CLIPSegForImageSegmentation

        processor = CLIPSegProcessor.from_pretrained("CIDAS/clipseg-rd64-refined")
        seg_model = CLIPSegForImageSegmentation.from_pretrained("CIDAS/clipseg-rd64-refined")

        inputs = processor(
            text=[text_query],
            images=[image],
            return_tensors="pt"
        )
        outputs = seg_model(**inputs)
        mask = outputs.logits.squeeze().sigmoid().detach().numpy()

        # Бінаризуємо
        mask_binary = (mask > 0.5).astype(np.uint8) * 255
        return Image.fromarray(mask_binary).resize(image.size)

    def mask_by_coords(self, image: Image.Image, bbox: tuple) -> Image.Image:
        """Маска за bounding box"""
        x1, y1, x2, y2 = bbox
        mask = Image.new("L", image.size, 0)
        draw = ImageDraw.Draw(mask)
        draw.rectangle([x1, y1, x2, y2], fill=255)
        return mask

Типові сценарії

class InpaintingUseCases:
    async def remove_object(self, image: bytes, object_mask: bytes) -> bytes:
        """Видаляємо об'єкт, заповнюємо фоном"""
        return self.pipe.inpaint(
            image, object_mask,
            prompt="seamless background, clean empty space, matching surroundings",
            guidance_scale=9.0
        )

    async def replace_background(self, image: bytes, subject_mask_inverted: bytes, new_background: str) -> bytes:
        """Змінюємо фон при утриманні суб'єкта"""
        return self.pipe.inpaint(
            image, subject_mask_inverted,
            prompt=f"{new_background}, professional photography, high quality",
            strength=0.95
        )

    async def change_product_color(self, product_image: bytes, product_mask: bytes, color: str) -> bytes:
        """Змінюємо колір товару для каталогу"""
        return self.pipe.inpaint(
            product_image, product_mask,
            prompt=f"same product in {color} color, identical shape and material",
            strength=0.7,  # низький strength зберігає форму
            guidance_scale=10.0
        )

API endpoint

from fastapi import FastAPI, File, UploadFile, Form

app = FastAPI()
inpainting = InpaintingService()

@app.post("/inpaint")
async def inpaint_image(
    image: UploadFile = File(...),
    mask: UploadFile = File(...),
    prompt: str = Form(...),
    strength: float = Form(0.99)
):
    image_bytes = await image.read()
    mask_bytes = await mask.read()

    result = inpainting.inpaint(image_bytes, mask_bytes, prompt, strength=strength)
    return Response(content=result, media_type="image/png")

Терміни: базовий API інпейнтингу — 2–3 дні. Сервіс з автосегментацією за кліком/текстом та веб-інтерфейсом — 2–3 тижні.