Spaces:
Sleeping
Sleeping
import os | |
os.system("wget https://dl.fbaipublicfiles.com/segment_anything/sam_vit_b_01ec64.pth -O sam_vit_b.pth") | |
import gradio as gr | |
import numpy as np | |
import torch | |
import cv2 | |
from PIL import Image | |
from segment_anything import sam_model_registry, SamPredictor | |
# SAM モデルの準備(適宜モデルパスを指定) | |
DEVICE = 'cuda' if torch.cuda.is_available() else 'cpu' | |
sam = sam_model_registry["vit_b"](checkpoint="sam_vit_b.pth").to(DEVICE) | |
predictor = SamPredictor(sam) | |
def process_image_with_mask(editor_value): | |
# 'composite' から合成画像を取得 | |
composite = editor_value.get("composite", None) | |
if composite is None: | |
return None # 合成画像がない場合は処理を終了 | |
# 'layers' からマスクを取得(最初のレイヤーを使用) | |
layers = editor_value.get("layers", []) | |
if not layers: | |
return composite # レイヤーがない場合は合成画像をそのまま返す | |
mask = layers[0] | |
# 画像とマスクを numpy 配列に変換 | |
img_np = np.array(composite.convert("RGB")) | |
mask_np = np.array(mask.convert("L")) | |
# SAM による予測対象のセット | |
predictor.set_image(img_np) | |
# マスクされたピクセル座標を取得 | |
yx = np.argwhere(mask_np > 127) | |
if len(yx) == 0: | |
return composite # マスクがない場合は合成画像をそのまま返す | |
input_points = np.flip(yx, axis=1) # (y, x) → (x, y) | |
input_labels = np.ones(len(input_points)) | |
masks, _, _ = predictor.predict( | |
point_coords=input_points, | |
point_labels=input_labels, | |
multimask_output=False | |
) | |
mask_out = masks[0] | |
# 背景を透明に | |
img_rgba = composite.convert("RGBA") | |
img_array = np.array(img_rgba) | |
img_array[mask_out] = [0, 0, 0, 0] # 該当領域を透明に | |
return Image.fromarray(img_array) | |
# UI 側 | |
with gr.Blocks() as demo: | |
gr.Markdown("## 手描きマスクから物体を削除・透明化") | |
editor = gr.ImageEditor(label="画像にマスクを描いてください", type="pil") | |
with gr.Row(): | |
process_btn = gr.Button("物体を削除(透明化)") | |
output = gr.Image(label="出力画像", type="pil") | |
process_btn.click( | |
fn=process_image_with_mask, | |
inputs=[editor], | |
outputs=output | |
) | |
demo.launch() | |