Создание эффекта портретного режима с помощью модели Segment Anything 2 (SAM2)

 Create Portrait Mode Effect with Segment Anything Model 2 (SAM2)

“`html

Создание эффекта портретного режима с помощью модели Segment Anything 2 (SAM2)

Вы когда-нибудь замечали, как камеры смартфонов выделяют основной объект, размывая фон? Этот эффект придаёт фотографиям профессиональный вид. В этом руководстве мы покажем, как создать этот эффект с помощью открытых моделей компьютерного зрения.

Инструменты и технологии

  • Модель Segment Anything (SAM2): для сегментации объектов и отделения переднего плана от фона.
  • Модель оценки глубины: для вычисления карты глубины и размывания фона.
  • Гауссово размытие: для размытия фона в зависимости от глубины.

Шаг 1: Настройка окружения

Установите необходимые зависимости:

pip install matplotlib samv2 pytest opencv-python timm pillow

Шаг 2: Загрузка изображения

Выберите изображение и загрузите его с помощью библиотеки Pillow:

from PIL import Image
import numpy as np
import matplotlib.pyplot as plt

image_path = "<путь к вашему изображению>.jpg"
img = Image.open(image_path)
img_array = np.array(img)

plt.imshow(img)
plt.axis("off")
plt.show()

Шаг 3: Инициализация SAM2

Скачайте предобученную модель. Мы будем использовать вариант tiny для быстрой работы:

from sam2.build_sam import build_sam2
from sam2.sam2_image_predictor import SAM2ImagePredictor
from sam2.utils.misc import variant_to_config_mapping
from sam2.utils.visualization import show_masks

model = build_sam2(
    variant_to_config_mapping["tiny"],
    "sam2_hiera_tiny.pt",
)
image_predictor = SAM2ImagePredictor(model)

Шаг 4: Выбор объекта

Установите изображение в SAM и укажите точки на объекте:

image_predictor.set_image(img_array)
input_point = np.array([[2500, 1200], [2500, 1500], [2500, 2000]])
input_label = np.array([1, 1, 1])

masks, scores, logits = image_predictor.predict(
    point_coords=input_point,
    point_labels=input_label,
    box=None,
    multimask_output=True,
)
output_mask = show_masks(img_array, masks, scores)
sorted_ind = np.argsort(scores)[::-1]

Шаг 5: Инициализация модели оценки глубины

Используем MiDaS для оценки глубины:

import torch
import torchvision.transforms as transforms

model_type = "DPT_Large"

model = torch.hub.load("intel-isl/MiDaS", model_type)
model.eval()

transform = torch.hub.load("intel-isl/MiDaS", "transforms").dpt_transform
input_batch = transform(img_array)

with torch.no_grad():
    prediction = model(input_batch)
    prediction = torch.nn.functional.interpolate(
        prediction.unsqueeze(1),
        size=img_array.shape[:2],
        mode="bicubic",
        align_corners=False,
    ).squeeze()

prediction = prediction.cpu().numpy()

plt.imshow(prediction, cmap="plasma")
plt.colorbar(label="Относительная глубина")
plt.title("Визуализация карты глубины")
plt.show()

Шаг 6: Применение глубинного размытия

Оптимизируем размытие на основе глубины:

import cv2

def apply_depth_based_blur_iterative(image, depth_map, base_kernel_size=7, max_repeats=10):
    if base_kernel_size % 2 == 0:
        base_kernel_size += 1

    depth_map = np.max(depth_map) - depth_map
    depth_normalized = cv2.normalize(depth_map, None, 0, max_repeats, cv2.NORM_MINMAX).astype(np.uint8)

    blurred_image = image.copy()

    for repeat in range(1, max_repeats + 1):
        mask = (depth_normalized == repeat)
        if np.any(mask):
            blurred_temp = cv2.GaussianBlur(blurred_image, (base_kernel_size, base_kernel_size), 0)
            for c in range(image.shape[2]):
                blurred_image[..., c][mask] = blurred_temp[..., c][mask]

    return blurred_image

blurred_image = apply_depth_based_blur_iterative(img_array, prediction, base_kernel_size=35, max_repeats=20)

plt.figure(figsize=(20, 10))
plt.subplot(1, 2, 1)
plt.imshow(img)
plt.title("Оригинальное изображение")
plt.axis("off")

plt.subplot(1, 2, 2)
plt.imshow(blurred_image)
plt.title("Изображение с размытием по глубине")
plt.axis("off")
plt.show()

Шаг 7: Объединение переднего плана и фона

Используйте маску SAM для извлечения четкого переднего плана:

def combine_foreground_background(foreground, background, mask):
    if mask.ndim == 2:
        mask = np.expand_dims(mask, axis=-1)
    return np.where(mask, foreground, background)

mask = masks[sorted_ind[0]].astype(np.uint8)
mask = cv2.resize(mask, (img_array.shape[1], img_array.shape[0]))
foreground = img_array
background = blurred_image

combined_image = combine_foreground_background(foreground, background, mask)

plt.figure(figsize=(20, 10))
plt.subplot(1, 2, 1)
plt.imshow(img)
plt.title("Оригинальное изображение")
plt.axis("off")

plt.subplot(1, 2, 2)
plt.imshow(combined_image)
plt.title("Эффект портретного режима")
plt.axis("off")
plt.show()

Заключение

Мы создали эффект портретного режима с помощью нескольких инструментов. Эта техника может быть полезна для редактирования фотографий и творческих проектов.

Будущие улучшения:

  • Использование алгоритмов обнаружения краев для улучшения контуров объектов.
  • Эксперименты с размерами ядер для улучшения эффекта размытия.
  • Создание интерфейса для загрузки изображений и динамического выбора объектов.

Как ИИ может помочь вашему бизнесу

Если вы хотите, чтобы ваша компания развивалась с помощью ИИ, проанализируйте, как он может изменить вашу работу. Определите, где возможно применение автоматизации и какие ключевые показатели эффективности (KPI) вы хотите улучшить.

Выберите подходящее решение из множества доступных вариантов ИИ. Начните с небольшого проекта, анализируйте результаты и расширяйте автоматизацию на основе полученных данных.

Если вам нужны советы по внедрению ИИ, пишите нам в Telegram. Следите за новостями о ИИ в нашем канале или в Twitter.

Попробуйте AI Sales Bot — этот ИИ ассистент в продажах поможет вам отвечать на вопросы клиентов и снижать нагрузку на первую линию.

“`

Полезные ссылки: