はじめに(概要)
最近、業務でSAMという強力なAIモデルを知ったので、その共有と実際に作成したコードを共有するために作成しました。
- 対象読者:AIエンジニア/Webエンジニア
- 記事の目的:モデルとモデルを利用して作成したコードの共有
背景・動機
業務でAI開発を行っているのですが、とあるモデルで最近業務の方でも成果
SAM(Segment Anything Model)について
SAMとはMeta社が開発した画像認識モデルです。以下GitaHubの説明(https://github.com/facebookresearch/segment-anything?tab=readme-ov-file )を翻訳したものです
Segment Anything Model(SAM)は、点やバウンディングボックスといった入力プロンプトから高品質な物体マスクを生成できるモデルであり、画像内のすべての物体に対するマスクを生成することが可能です。1,100 万枚の画像と 11 億枚のマスクからなるデータセットで学習されており、さまざまなセグメンテーションタスクにおいて強力なゼロショット性能を発揮します。
環境
動作確認を行った環境を明示します。
OS:Windows11
Python:3.10
実装例
コードを実行すると、ウィンドウが表示されてそこから切り抜きたい部分を複数個クリックすることで切り抜けるようにしてあります。
import cv2
import numpy as np
import torch
from segment_anything import sam_model_registry, SamPredictor
# =====================================================
# 設定
# =====================================================
IMAGE_PATH = "sample.jpg"
SAM_CHECKPOINT = "sam_vit_h_4b8939.pth"
MODEL_TYPE = "vit_h"
DEVICE = "cuda" if torch.cuda.is_available() else "cpu"
# =====================================================
# SAM モデルロード
# =====================================================
sam = sam_model_registry[MODEL_TYPE](checkpoint=SAM_CHECKPOINT)
sam.to(device=DEVICE)
predictor = SamPredictor(sam)
# =====================================================
# 画像読み込み
# =====================================================
image = cv2.imread(IMAGE_PATH)
if image is None:
raise FileNotFoundError(f"画像が見つかりません: {IMAGE_PATH}")
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
display_image = image.copy()
predictor.set_image(image)
# =====================================================
# マウスクリック取得
# =====================================================
clicked_points = []
def mouse_callback(event, x, y, flags, param):
if event == cv2.EVENT_LBUTTONDOWN:
clicked_points.append([x, y])
cv2.circle(display_image, (x, y), 5, (255, 0, 0), -1)
cv2.imshow("click", cv2.cvtColor(display_image, cv2.COLOR_RGB2BGR))
cv2.imshow("click", cv2.cvtColor(display_image, cv2.COLOR_RGB2BGR))
cv2.setMouseCallback("click", mouse_callback)
print("左クリックで複数点指定 / Enterで確定 / Escで終了")
while True:
key = cv2.waitKey(1)
if key == 13: # Enter
break
if key == 27: # Esc
cv2.destroyAllWindows()
exit()
cv2.destroyAllWindows()
if len(clicked_points) == 0:
raise RuntimeError("クリック点が指定されていません")
# =====================================================
# SAM 推論(複数点)
# =====================================================
input_points = np.array(clicked_points)
input_labels = np.ones(len(clicked_points)) # 全点を前景
masks, scores, _ = predictor.predict(
point_coords=input_points,
point_labels=input_labels,
multimask_output=True,
)
# 最もスコアの高いマスクを採用
mask = masks[np.argmax(scores)]
# =====================================================
# 背景透過 PNG 作成
# =====================================================
h, w, _ = image.shape
# RGBA 画像作成
rgba = np.zeros((h, w, 4), dtype=np.uint8)
rgba[..., :3] = image
rgba[..., 3] = (mask * 255).astype(np.uint8)
# マスク領域でトリミング
ys, xs = np.where(mask)
min_x, max_x = xs.min(), xs.max()
min_y, max_y = ys.min(), ys.max()
cropped_rgba = rgba[min_y:max_y, min_x:max_x]
# =====================================================
# 保存(透過 PNG)
# =====================================================
cv2.imwrite(
"cropped_transparent.png",
cv2.cvtColor(cropped_rgba, cv2.COLOR_RGBA2BGRA)
)
print("保存完了: cropped_transparent.png(背景透過)")
実行結果・動作確認
- 実行結果の例
- スクリーンショット(必要であれば)
- 想定通り動作したか
生成AIとの比較
世にあるAIサービスとの比較を行っていきたいと思います。ここではNanoBananaと比較してみようと思います
比較について
こちらのフリー画像を用いて切り取りたい箇所を指定してみて比較をしてみようかと思います。

人物を指定した場合

生成系との比較
生成系を使うと1から画像を作ることになるので、完全に同じものが出力されるわけではない
まぁどちらにせよ、無料でこんだけキレイに切り取れるという点は非常に強力だと思います
用途
用途としては、機械学習させるときに背景を切り取る必要があるのでそういう時に使い勝手がいいかも
後は実務だと情報流出するリスクとかがあるのでローカルでできるという点も魅力の一つだと思います
参考リンク
参考にした記事や公式ドキュメントを記載します。
- SAMの公式GitHub(https://github.com/facebookresearch/segment-anything )
おわりに
いいねもらえたら励みになります。ぜひともお願いします
