Crie um efeito de modo retrato com Segment Anything Model 2 (SAM2)
Inteligência artificial

Crie um efeito de modo retrato com Segment Anything Model 2 (SAM2)


Você já admirou como as câmeras dos celulares isolam o assunto principal do fundo, adicionando um desfoque sutil ao fundo com base na profundidade? Este efeito de “modo retrato” dá às fotos uma aparência profissional, simulando uma profundidade de campo rasa semelhante às câmeras DSLR. Neste tutorial, recriaremos esse efeito programaticamente usando modelos de visão computacional de código aberto, como SAM2 da Meta e MiDaS da Intel ISL.

Para construir nosso pipeline, usaremos:

  1. Segmentar qualquer modelo (SAM2): Para separar objetos de interesse e separar primeiro e segundo plano.
  2. Modelo de estimativa de profundidade: Calculando o mapa de profundidade, permite desfoque baseado em profundidade.
  3. Desfoque gaussiano: desfoque o fundo com intensidade variável com base na profundidade.

Etapa 1: Configurando o Ambiente

Para começar, instale as seguintes dependências:

pip install matplotlib samv2 pytest opencv-python timm pillow

Etapa 2: carrega a imagem de destino

Selecione uma imagem para usar este efeito e carregue-a em Python usando o Um travesseiro a biblioteca.

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)

# Display the image
plt.imshow(img)
plt.axis("off")
plt.show()

Etapa 3: iniciar o SAM2

Para executar o modelo, baixe um ambiente de teste pré-treinado. O SAM2 oferece quatro variantes baseadas no desempenho e na velocidade de decisão: mínimo, mínimo, base_plus e grande. Neste tutorial, usaremos um pouco para um rápido entendimento.

Baixe o ponto de verificação do modelo em: https://dl.fbaipublicfiles.com/segment_anything_2/072824/sam2_hiera_.pt

Substitua com o tipo de modelo que você deseja.

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)

Passo 4: Insira a imagem no SAM e selecione um título

Defina a imagem no SAM e atribua pontos que estejam no assunto que você deseja segmentar. SAM prevê uma máscara binária para o sujeito e o domínio.

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]

Etapa 5: execute o modelo de estimativa de profundidade

Para medir a profundidade, usamos MiDaS pela Intel ISL. Semelhante ao SAM, você pode escolher variantes com base na precisão e velocidade.Tome cuidado: O mapa de profundidade previsto é invertido, o que significa que valores maiores correspondem a objetos mais próximos. Iremos convertê-lo na próxima etapa para melhor compreensão.

import torch
import torchvision.transforms as transforms

model_type = "DPT_Large"  # MiDaS v3 - Large (highest accuracy)

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

# Load and preprocess image
transform = torch.hub.load("intel-isl/MiDaS", "transforms").dpt_transform
input_batch = transform(img_array)

# Perform depth estimation
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()

# Visualize the depth map
plt.imshow(prediction, cmap="plasma")
plt.colorbar(label="Relative Depth")
plt.title("Depth Map Visualization")
plt.show()

Etapa 6: aplicar desfoque gaussiano baseado em profundidade

Aqui implementamos o desfoque baseado em profundidade usando um método iterativo de desfoque gaussiano. Em vez de usar um kernel grande, usamos um kernel pequeno várias vezes para pixels com valores de profundidade altos.

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

    # Invert depth map
    depth_map = np.max(depth_map) - depth_map

    # Normalize depth to range [0, max_repeats]
    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)

# Visualize the result
plt.figure(figsize=(20, 10))
plt.subplot(1, 2, 1)
plt.imshow(img)
plt.title("Original Image")
plt.axis("off")

plt.subplot(1, 2, 2)
plt.imshow(blurred_image)
plt.title("Depth-based Blurred Image")
plt.axis("off")
plt.show()

Etapa 7: junte o plano de fundo ao plano de fundo

Finalmente, use uma máscara SAM para remover o primeiro plano nítido e misturá-lo com o fundo desfocado.

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("Original Image")
plt.axis("off")

plt.subplot(1, 2, 2)
plt.imshow(combined_image)
plt.title("Final Portrait Mode Effect")
plt.axis("off")
plt.show()

A conclusão

Com apenas algumas ferramentas, recriamos o efeito do modo retrato de forma programática. Essa técnica pode ser estendida a aplicativos de edição de fotos, simulação de efeitos de câmera ou projetos criativos.

Melhorias Futuras:

  1. Use algoritmos de detecção de bordas para aprimorar melhor as bordas do assunto.
  2. Experimente o tamanho do kernel para melhorar o efeito de desfoque.
  3. Crie uma interface de usuário para fazer upload de imagens e selecionar tópicos dinamicamente.

Recursos:

  1. Segmente qualquer modelo com META (
  2. Uma implementação compatível com CPU do SAM 2 (
  3. O modelo de estimativa de profundidade MIDAs (


Vineet Kumar é estagiário de consultoria na MarktechPost. Atualmente, ele está cursando seu bacharelado no Instituto Indiano de Tecnologia (IIT), Kanpur. Ele é um entusiasta do aprendizado de máquina. Ele está interessado em pesquisas e desenvolvimentos recentes em Deep Learning, Visão Computacional e áreas afins.

📄 Conheça 'Height': ferramenta independente de gerenciamento de projetos (patrocinado)



Source link

Você também pode gostar...

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *