SAM 예제
실제 코드로 SAM 3의 주요 기능을 익힌다. 텍스트 프롬프트부터 YOLO와의 통합, 배치 처리까지 철도 점검 프로젝트에 바로 적용할 수 있는 예제를 다룬다.
| 항목 | 내용 |
|---|---|
| 핵심 활용법 | 텍스트 프롬프트로 YOLO 학습 라벨 자동 생성 |
| 권장 GPU | VRAM 8GB 이상 (half=True 옵션 활용 시) |
| 주요 예제 | 자동 라벨링, YOLO+SAM 하이브리드, 배치 처리 |
문서 탐색
예제 1: 텍스트로 객체 세그멘테이션
가장 기본적인 예제다. "person"과 "bus"를 텍스트로 지정하여 이미지에서 자동으로 찾아낸다.
from ultralytics.models.sam import SAM3SemanticPredictor
import cv2
# 예측기 초기화
overrides = dict(
conf=0.25,
task="segment",
mode="predict",
model="sam3.pt",
half=True,
save=True
)
predictor = SAM3SemanticPredictor(overrides=overrides)
# 이미지 설정
predictor.set_image("bus.jpg")
# 텍스트 프롬프트로 세그멘테이션
results = predictor(text=["person", "bus"])
# 결과 시각화
for result in results:
# 마스크 정보 출력
if result.masks is not None:
print(f"탐지된 객체 수: {len(result.masks)}")
for i, mask in enumerate(result.masks.data):
print(f" 객체 {i}: 마스크 크기 {mask.shape}")
# 결과 이미지 저장
result.save("output_segmented.jpg")
print("결과 저장 완료: output_segmented.jpg")예제 2: SAM 3로 YOLO 학습 데이터 자동 생성
이것이 철도 프로젝트에서 SAM 3를 활용하는 핵심 방법이다. 수동 라벨링 없이 텍스트 프롬프트만으로 YOLO 학습 데이터를 자동 생성한다.
from ultralytics.models.sam import SAM3SemanticPredictor
import os
# 클래스 정의 (YOLO 학습 시 사용할 순서와 동일하게)
CLASSES = ["rail", "sleeper", "catenary pole"]
# 예측기 초기화
overrides = dict(conf=0.25, task="segment", mode="predict",
model="sam3.pt", half=True, save=False)
predictor = SAM3SemanticPredictor(overrides=overrides)
def generate_yolo_label(image_path, output_dir):
"""드론 사진 한 장에서 YOLO 라벨 파일(.txt)을 자동 생성한다."""
predictor.set_image(image_path)
# 모든 클래스를 한 번에 요청
results = predictor(text=CLASSES)
# 이미지 크기 파악
img_h, img_w = results[0].orig_shape
label_lines = []
for result in results:
if result.boxes is None:
continue
for i, box in enumerate(result.boxes):
# 클래스 ID 획득
class_id = int(box.cls.item())
# 바운딩 박스를 YOLO 형식으로 변환 (정규화된 cx, cy, w, h)
x1, y1, x2, y2 = box.xyxy[0].tolist()
cx = (x1 + x2) / 2 / img_w
cy = (y1 + y2) / 2 / img_h
w = (x2 - x1) / img_w
h = (y2 - y1) / img_h
label_lines.append(f"{class_id} {cx:.6f} {cy:.6f} {w:.6f} {h:.6f}")
# 라벨 파일 저장
base_name = os.path.splitext(os.path.basename(image_path))[0]
label_path = os.path.join(output_dir, base_name + ".txt")
os.makedirs(output_dir, exist_ok=True)
with open(label_path, "w") as f:
f.write("\n".join(label_lines))
print(f"라벨 생성 완료: {label_path} ({len(label_lines)}개 객체)")
return label_path
# 사용 예시
generate_yolo_label("drone_railway_001.jpg", "labels/train")핵심 장점: 이 방법으로 수백 장의 드론 사진에 대한 YOLO 학습 데이터를 몇 분 안에 생성할 수 있다. 수동 라벨링 대비 시간을 90% 이상 절감하는 것이 가능하다.
예제 3: YOLO + SAM 하이브리드 파이프라인
YOLO의 속도와 SAM의 정밀도를 결합한 파이프라인이다. 실시간에 가까운 속도로 정밀한 마스크를 얻을 수 있다.
from ultralytics import YOLO, SAM
# Step 1: YOLO로 빠른 탐지
yolo_model = YOLO("best.pt") # 철도 결함 탐지 학습된 모델
yolo_results = yolo_model.predict("drone_railway.jpg", conf=0.5)
# Step 2: YOLO 바운딩 박스를 SAM에 전달하여 정밀 마스크 획득
sam_model = SAM("sam3.pt")
for yolo_result in yolo_results:
if yolo_result.boxes is None or len(yolo_result.boxes) == 0:
print("탐지된 객체 없음")
continue
# YOLO가 탐지한 바운딩 박스 추출
bboxes = yolo_result.boxes.xyxy.tolist()
class_ids = yolo_result.boxes.cls.tolist()
print(f"YOLO 탐지 수: {len(bboxes)}")
# SAM으로 각 박스에 대한 정밀 마스크 생성
sam_results = sam_model.predict(
"drone_railway.jpg",
bboxes=bboxes
)
for i, sam_result in enumerate(sam_results):
class_name = yolo_model.names[int(class_ids[i])]
print(f" {class_name}: 마스크 픽셀 수 = {sam_result.masks.data[0].sum().item():.0f}")
sam_results[0].save("hybrid_output.jpg")
print("하이브리드 결과 저장 완료")예제 4: 여러 이미지 배치 처리
드론으로 촬영한 폴더 전체를 한 번에 자동 라벨링한다.
from ultralytics.models.sam import SAM3SemanticPredictor
import os
from pathlib import Path
CLASSES = ["rail", "sleeper", "catenary pole", "crack", "rust"]
overrides = dict(conf=0.25, task="segment", mode="predict",
model="sam3.pt", half=True, save=False)
predictor = SAM3SemanticPredictor(overrides=overrides)
def batch_label_folder(image_dir, label_dir):
"""폴더 내 모든 이미지에 대해 자동 라벨 생성."""
image_dir = Path(image_dir)
label_dir = Path(label_dir)
label_dir.mkdir(parents=True, exist_ok=True)
# 지원 이미지 확장자
image_files = list(image_dir.glob("*.jpg")) + \
list(image_dir.glob("*.png")) + \
list(image_dir.glob("*.jpeg"))
print(f"처리할 이미지: {len(image_files)}장")
for idx, image_path in enumerate(image_files):
print(f"[{idx+1}/{len(image_files)}] {image_path.name} 처리 중...")
predictor.set_image(str(image_path))
results = predictor(text=CLASSES)
img_h, img_w = results[0].orig_shape
label_lines = []
for result in results:
if result.boxes is None:
continue
for box in result.boxes:
class_id = int(box.cls.item())
x1, y1, x2, y2 = box.xyxy[0].tolist()
cx = (x1 + x2) / 2 / img_w
cy = (y1 + y2) / 2 / img_h
w = (x2 - x1) / img_w
h = (y2 - y1) / img_h
label_lines.append(
f"{class_id} {cx:.6f} {cy:.6f} {w:.6f} {h:.6f}"
)
label_path = label_dir / (image_path.stem + ".txt")
label_path.write_text("\n".join(label_lines))
print(f"\n완료! {len(image_files)}개 라벨 파일 생성 -> {label_dir}")
# 사용 예시
batch_label_folder("drone_images/train", "labels/train")
batch_label_folder("drone_images/val", "labels/val")예제 5: Feature 재사용으로 효율적 다중 쿼리
set_image()를 한 번만 호출하면 이미지의 Feature를 메모리에 캐싱한다. 같은 이미지에 여러 텍스트 쿼리를 날릴 때 이미지 인코딩을 반복하지 않아 속도가 크게 향상된다.
from ultralytics.models.sam import SAM3SemanticPredictor
overrides = dict(conf=0.25, task="segment", mode="predict",
model="sam3.pt", half=True, save=False)
predictor = SAM3SemanticPredictor(overrides=overrides)
# 이미지 Feature는 한 번만 추출 (가장 시간이 오래 걸리는 부분)
predictor.set_image("drone_railway.jpg")
# 이후 여러 쿼리는 Feature 재사용으로 빠르게 처리
rail_results = predictor(text=["rail"])
sleeper_results = predictor(text=["sleeper"])
crack_results = predictor(text=["crack", "rust", "corrosion"])
print(f"레일 탐지: {len(rail_results[0].boxes) if rail_results[0].boxes else 0}개")
print(f"침목 탐지: {len(sleeper_results[0].boxes) if sleeper_results[0].boxes else 0}개")
print(f"결함 탐지: {len(crack_results[0].boxes) if crack_results[0].boxes else 0}개")SAM vs YOLO 사용 시나리오 가이드
| 시나리오 | 추천 | 이유 |
|---|---|---|
| 자동 라벨링 | SAM 3 | 텍스트 프롬프트로 즉시 사용, 학습 불필요 |
| 실시간 탐지 | YOLO | 속도 10배+ 빠름 |
| 프로토타이핑 | SAM 3 | Zero-shot으로 바로 결과 확인 |
| 프로덕션 배포 | YOLO | 경량, 엣지 디바이스 호환 |
| 정밀 마스크 필요 | SAM 3 | 픽셀 단위 세그멘테이션 |
| 상업적 사용 | SAM 3 (Apache 2.0) | YOLO(AGPL-3.0)보다 라이선스 자유로움 |
추천 워크플로우: SAM 3로 자동 라벨 생성 → 라벨 검수 → YOLO 학습 → 현장 배포. 이 파이프라인이 현재 철도 점검 시스템 구축에 가장 현실적인 접근법이다.