본문 바로가기
Artificial Intelligence/60. Python

[PYTHON] 시각 지능 혁신을 위한 SAM 실전 응용 방법과 성능 최적화 7가지 해결책

by Papa Martino V 2026. 4. 13.
728x90

Segment Anything Model(SAM)
Segment Anything Model (SAM)

1. 시각 지능의 새로운 패러다임: Segment Anything Model(SAM)의 가치

현대 컴퓨터 비전 분야에서 Segment Anything Model (SAM)은 가히 혁명적인 변화를 불러일으켰습니다. 과거에는 특정 객체를 검출하거나 분할하기 위해 수천 장의 라벨링된 데이터와 개별적인 모델 학습이 필수적이었습니다. 하지만 Meta AI에서 공개한 SAM은 '제로샷(Zero-shot)' 성능을 기반으로, 학습하지 않은 객체에 대해서도 정교한 마스크를 생성하는 놀라운 능력을 보여줍니다.  포스팅에서는 단순한 이론을 넘어, Python을 활용하여 실무에서 즉시 활용 가능한 SAM의 응용 방법과 프로젝트에서 마주치는 병목 현상을 해결하는 7가지 구체적인 Example을 제안합니다. 시각 지능 서비스를 구축하려는 개발자라면 이 가이드가 기술적 도약의 발판이 될 것입니다.


2. 기존 이미지 세그멘테이션 기술과 SAM의 차이점 비교

SAM이 기존의 Mask R-CNN이나 U-Net 기반 모델들과 어떻게 다른지 이해하는 것은 아키텍처 설계에 있어 매우 중요합니다. 아래 표를 통해 주요 차이점을 확인해 보십시오.

비교 항목 기존 Deep Learning 모델 (예: U-Net) Segment Anything Model (SAM)
학습 데이터 요구량 특정 도메인별 대량의 라벨링 데이터 필수 11억 개의 마스크로 사전 학습 (추가 학습 불필요)
범용성 (Generalization) 학습된 클래스에 대해서만 작동 처음 보는 객체도 즉시 분할 가능 (Zero-shot)
입력 방식 (Prompting) 고정된 이미지 입력 포인트, 박스, 텍스트 등 다양한 프롬프트 대응
실시간성 경량화 시 실시간 가능 Heavy한 인코더로 인해 고성능 GPU 필수
주요 활용처 특정 의료 영상 분석, 자율주행 도로 인식 범용 이미지 편집, 자동 라벨링 도구, AR/VR

3. 실무 적용을 위한 SAM 실전 응용 Example (Python)

SAM을 프로젝트에 도입할 때 즉시 복사하여 사용할 수 있는 7가지 핵심 구현 예제입니다. segment_anything 라이브러리와 PyTorch 기반으로 작성되었습니다.

Example 1: 단일 포인트 프롬프트를 활용한 객체 추출

import torch
import cv2
from segment_anything import sam_model_registry, SamPredictor

# 모델 로드 (ViT-H 버전)
sam_checkpoint = "sam_vit_h_4b8939.pth"
model_type = "vit_h"
device = "cuda" if torch.cuda.is_available() else "cpu"

sam = sam_model_registry[model_type](checkpoint=sam_checkpoint)
sam.to(device=device)
predictor = SamPredictor(sam)

# 이미지 읽기 및 설정
image = cv2.imread('input_scene.jpg')
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
predictor.set_image(image)

# 클릭한 지점(포인트) 설정 [x, y]
input_point = np.array([[500, 375]])
input_label = np.array([1]) # 1은 전경(Foreground) 의미

masks, scores, logits = predictor.predict(
    point_coords=input_point,
    point_labels=input_label,
    multimask_output=True,
)
        

Example 2: Bounding Box를 활용한 정밀 객체 마스킹

# 탐지된 박스 좌표 [x1, y1, x2, y2]
input_box = np.array([425, 600, 700, 875])

masks, _, _ = predictor.predict(
    box=input_box,
    multimask_output=False,
)

# 마스크 결과를 활용한 배경 제거(Alpha Channel 생성)
mask = masks[0].astype(np.uint8) * 255
        

Example 3: 이미지 전체 자동 세그멘테이션 (Automatic Mask Generation)

from segment_anything import SamAutomaticMaskGenerator

mask_generator = SamAutomaticMaskGenerator(sam)
masks = mask_generator.generate(image)

# 결과: 이미지 내 모든 가능한 객체에 대한 마스크 리스트 반환
# masks[0]['segmentation'] -> 불리언 마스크
# masks[0]['area'] -> 객체 면적
        

Example 4: ONNX Export를 통한 웹/모바일 추론 가속화

import onnx
from segment_anything.utils.onnx import SamOnnxModel

onnx_model_path = "sam_onnx_model.onnx"
onnx_model = SamOnnxModel(sam, return_single_mask=True)

dynamic_axes = {
    "point_coords": {1: "num_points"},
    "point_labels": {1: "num_points"},
}

# 더미 데이터 입력 후 추출
torch.onnx.export(
    onnx_model,
    (dummy_image_embedding, dummy_point_coords, dummy_point_labels, dummy_mask_input, dummy_has_mask_input, dummy_orig_im_size),
    onnx_model_path,
    export_params=True,
    opset_version=17,
    do_constant_folding=True,
    input_names=["image_embeddings", "point_coords", "point_labels", "mask_input", "has_mask_input", "orig_im_size"],
    output_names=["masks", "iou_predictions", "low_res_masks"],
    dynamic_axes=dynamic_axes,
)
        

Example 5: 특정 객체 제외(Negative Prompt)를 통한 결과 정교화

# 포함할 포인트와 제외할 포인트를 섞어서 입력
input_points = np.array([[500, 375], [520, 400]])
input_labels = np.array([1, 0]) # 1: 포함, 0: 제외

masks, _, _ = predictor.predict(
    point_coords=input_points,
    point_labels=input_labels,
    multimask_output=False,
)
        

Example 6: 비디오 스트림 내 객체 추적 응용 (Frame-by-Frame)

cap = cv2.VideoCapture("video.mp4")
while cap.isOpened():
    ret, frame = cap.read()
    if not ret: break
    
    # SAM의 임베딩 계산은 무거우므로 실무에서는 
    # 첫 프레임만 SAM으로 마스크를 따고 이후는 Optical Flow나 
    # SAM-Track 같은 파생 모델을 사용함
    # 여기서는 간단히 프레임별 Predict 로직만 예시함
    predictor.set_image(cv2.cvtColor(frame, cv2.COLOR_BGR2RGB))
    # ... 이전 프레임의 박스 좌표를 업데이트하여 입력 ...
        

Example 7: Batch Processing을 통한 대량 이미지 라벨링 가속화

# 대량의 이미지를 처리할 때는 Image Encoder의 결과를 캐싱하여 사용
# 동일 이미지에 여러 프롬프트를 줄 때 유용
image_embedding = predictor.get_image_embedding()

for box in bboxes:
    masks, _, _ = predictor.predict_torch(
        point_coords=None,
        point_labels=None,
        boxes=torch.as_tensor(box, device=device),
        multimask_output=False,
    )
        

4. SAM 운영 시 반드시 고려해야 할 성능 최적화 방법

SAM은 매우 강력하지만 모델 파라미터가 커서(ViT-H 기준) 실시간 서빙에는 어려움이 따릅니다. 이를 해결하기 위한 3가지 실무 전략을 제시합니다.

  • 모델 경량화 (MobileSAM): 모바일이나 엣지 디바이스에서는 원본 SAM 대신 TinyViT을 기반으로 한 MobileSAM을 사용하십시오. 정확도는 약간 희생되지만 속도는 10배 이상 빠릅니다.
  • Mixed Precision 활용: PyTorch의 torch.cuda.amp를 사용하여 FP16 추론을 수행하면 메모리 점유율을 줄이고 속도를 높일 수 있습니다.
  • 임베딩 분리 서빙: 이미지 인코더(Heavy)와 마스크 디코더(Light)를 분리하십시오. 인코더 결과인 임베딩을 서버에 저장해두면, 클라이언트에서 포인트 클릭 시 디코더만 실행하여 50ms 내외의 반응 속도를 낼 수 있습니다.

5. 결론 및 향후 전망

SAM(Segment Anything Model)은 시각 지능을 개발하는 방식 자체를 바꾸고 있습니다. 이제 데이터 라벨러들은 수동으로 다각형(Polygon)을 그리는 대신, SAM이 제안한 영역을 수정하는 방식으로 업무를 전환하고 있습니다. 위에서 제시한 7가지 Python 예제와 비교 분석을 바탕으로, 여러분의 도메인(의료, 제조, 농업 등)에 맞는 최적의 시각 지능 솔루션을 구축해 보시기 바랍니다.

내용 출처

  • Meta AI Research: "Segment Anything" (2023)
  • Segment Anything Official GitHub Repository
  • PyTorch Documentation for Vision Models
  • Computer Vision Foundation (CVF) Conference Papers
728x90