컴퓨터 비전 통합 파이프라인 — YOLO·Faster R-CNN 탐지, U-Net 분할, 3D Vision 융합
객체 탐지(YOLO, Faster R-CNN), 이미지 분할(U-Net), 3D Vision을 하나의 추론 파이프라인으로 묶는 설계 기준과 코드, KPI를 정리한다.
2026-08-12 · 최초 발행 2025-12-11
라인 카메라가 결함을 잡아내는 것과 그 결함이 얼마나 깊은지 재는 것은 서로 다른 문제다. 결함 탐지에는 YOLO 같은 빠른 검출기가, 결함 영역을 픽셀 단위로 그리는 데는 U-Net이, 깊이를 재는 데는 스테레오나 단안 깊이 추정이 필요하다. 현업 비전 시스템은 결국 이 세 갈래 — 객체 탐지, 분할, 3D — 를 하나의 파이프라인으로 통합하는 설계 문제로 수렴한다. 실시간성·정확도·운영 편의성의 균형을 어디서 잡을지가 관건이고, 모델 버전과 벤치마크 지표는 계속 바뀌므로 최신 정보를 그때그때 확인해야 한다.
탐지·분할·3D는 각각 무엇을 재는가
객체 탐지는 이미지 안 객체의 위치(바운딩 박스)와 클래스를 식별하는 문제로, mAP@[.5:.95]·FPS·latency로 평가한다. YOLO 계열은 단일 단계 검출 방식이라 속도가 빠르고 임베디드·엣지에 적합하며 경량화와 TensorRT 최적화가 수월하다. Faster R-CNN은 2단계 검출로 정밀도가 높아 복잡한 장면이나 소객체에서 강점을 보이지만 추론 지연이 커진다.
분할은 픽셀 단위로 클래스를 할당하는 문제이고 mIoU·Dice·(의료 영상에서는) HD95로 평가한다. U-Net은 U자형 인코더-디코더 구조에 skip-connection을 더해 세부 구조를 보존하며, 소량 데이터에서도 강건하게 학습되고 다양한 백본·손실 함수 조합이 가능하다.
3D Vision은 깊이 추정·재구성·추적으로 공간을 인식하는 영역으로, 깊이 RMSE/AbsRel·포즈 ATE·재구성 정확도가 평가 지표다. 스테레오(SGBM), 단안 깊이(MiDaS 등), SLAM(ORB-SLAM), 신경 재구성(NeRF) 등 접근법이 있고, 캘리브레이션 품질과 텍스처·조명 조건에 민감하다는 공통 제약이 있다.
데이터부터 서빙까지, 무엇을 표준화해야 하는가
데이터 파이프라인은 수집→라벨링→검증→버전 관리→증강 순서를 표준화하고, COCO/VOC 포맷과 분할 마스크(폴리곤/비트맵)를 정합해야 한다. 3D를 쓴다면 카메라 내·외부 파라미터, 스테레오 정렬, 시간 동기화 관리가 별도로 필요하다.
모델 선택은 목적에 따라 갈린다. 실시간성이 우선이면 YOLO(S/N) + TensorRT/INT8로 지연 30ms 이하를 목표로 하고, 정밀도가 우선이면 Faster R-CNN에 높은 해상도와 TTA를 얹는다. 분할은 U-Net에 ResNet/EfficientNet 백본과 Dice/Focal 손실 조합을 쓰는 구성이 흔하다.
학습·최적화 단계에서는 Focal loss·CB loss와 클래스 재가중으로 데이터 불균형에 대응하고, 소객체 대응을 위해 멀티스케일과 mosaic/cutmix를 쓴다. AMP, gradient accumulation, EMA, Cosine LR, SWA로 성능을 튜닝하며, 3D는 캘리브레이션 오차를 에러 바운드로 반영해야 한다.
배포는 ONNX → TensorRT, OpenVINO, CoreML 경로를 표준화하고, 동형 테스트 세트로 정확도 회귀 테스트를 자동화한다. 관측성 측면에서는 mAP·mIoU·FPS·메모리를 지표로 수집하고 샘플링 기반 드리프트를 감지하며 실패 케이스를 자동으로 재학습 루프에 태운다.
파이프라인이 실제로 흐르는 순서
지연 예산을 못 맞추면 해상도·배치를 줄이거나 NMS 임계를 올리고 경량 모델로 스위치하는 폴백 경로가 있고, 3D 품질 검사에 실패하면 캘리브레이션을 재요청하거나 결과 없이 폴백·알림으로 넘어가는 구조다.
모델별로 무엇을 얻고 무엇을 감수하는가
| 모델/기능 | 성능(정확도/속도) | 확장성 | 일관성(도메인 전이) | 안정성(장애·노이즈) | 운영 편의 |
|---|---|---|---|---|---|
| YOLO | mAP 중~상, FPS 매우 높음(엣지 적합) | TensorRT/INT8로 수평 확장 용이 | 도메인 변화에 중간, 재학습 필요 | 조명·모션 블러에 중간 | 배포 용이, 생태계 풍부 |
| Faster R-CNN | mAP 상, FPS 낮음(지연 큼) | 배치 추론 확장 중간 | 복잡 장면·소객체에서 높음 | 안정성 높음, 다만 자원 요구 | 운영 중간, 튜닝 복잡 |
| U-Net | mIoU/Dice 상, 해상도 의존 | 패치·슬라이딩 윈도우로 높음 | 도메인 적응 시 높음 | 경계 노이즈에 강함 | 추론 파이프 간단 |
| 3D(스테레오/단안 깊이) | 깊이 RMSE 중, 환경 민감 | 멀티카메라·분산 처리로 중 | 텍스처·조명 변화에 민감 | 캘리브레이션·동기화에 민감 | 캘리브·동기화 관리 필요 |
코드로 보는 통합 추론
Python 3.10, PyTorch 2.2+, CUDA 12.x, NVIDIA GPU 환경을 전제로 한다.
pip install ultralytics segmentation-models-pytorch opencv-python onnxruntime
# PyTorch는 CUDA 버전에 맞춰 설치 필요: https://pytorch.org/get-started/locally/
import cv2
import torch
import numpy as np
from ultralytics import YOLO
import segmentation_models_pytorch as smp
# 1) 모델 로드
device = 'cuda' if torch.cuda.is_available() else 'cpu'
det = YOLO('yolov8n.pt') # 최신 가중치는 변경 가능, 최신 정보 확인 필요
# U-Net: 백본/클래스/활성화는 태스크에 맞게 조정
unet = smp.Unet(encoder_name='resnet34', encoder_weights=None, classes=1, activation=None).to(device)
unet_ckpt = 'unet_best.pth' # 사용자가 학습한 체크포인트
try:
unet.load_state_dict(torch.load(unet_ckpt, map_location=device))
unet.eval()
except FileNotFoundError:
print('[경고] U-Net 체크포인트 미존재, 세그멘테이션 생략 경로로 진행')
# 2) 입력 로드
img = cv2.imread('sample.jpg') # BGR
assert img is not None, '이미지 로드 실패'
rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
# 3) 객체 탐지
det_res = det.predict(rgb, imgsz=640, conf=0.25, device=0 if device=='cuda' else None, verbose=False)[0]
boxes = det_res.boxes.xyxy.cpu().numpy().astype(int) if det_res.boxes is not None else np.empty((0,4))
scores = det_res.boxes.conf.cpu().numpy() if det_res.boxes is not None else np.empty((0,))
cls_ids = det_res.boxes.cls.cpu().numpy().astype(int) if det_res.boxes is not None else np.empty((0,))
# 4) 선택적 세그멘테이션(ROI 크롭 → U-Net)
masks = []
if hasattr(unet, 'encoder') and len(boxes) > 0:
for (x1,y1,x2,y2) in boxes:
x1,y1 = max(0,x1), max(0,y1)
crop = rgb[y1:y2, x1:x2]
if crop.size == 0:
masks.append(None); continue
inp = cv2.resize(crop, (256,256))
ten = torch.from_numpy(inp.transpose(2,0,1)).float().unsqueeze(0)/255.0
ten = ten.to(device)
with torch.no_grad(), torch.autocast(device_type=device if device=='cuda' else 'cpu', enabled=(device=='cuda')):
logit = unet(ten)
prob = torch.sigmoid(logit).squeeze().cpu().numpy()
mask = cv2.resize((prob>0.5).astype(np.uint8)*255, (x2-x1, y2-y1))
masks.append((x1,y1,mask))
else:
masks = [None]*len(boxes)
# 5) 선택적 3D 깊이(스테레오 예시: 좌/우 이미지 입력 필요)
# 참고: 스테레오 캘리브레이션 파라미터 필수(최신 정보 확인 필요)
try:
left = cv2.imread('stereo_left.png', cv2.IMREAD_GRAYSCALE)
right = cv2.imread('stereo_right.png', cv2.IMREAD_GRAYSCALE)
if left is not None and right is not None:
sgbm = cv2.StereoSGBM_create(numDisparities=128, blockSize=5)
disp = sgbm.compute(left, right).astype(np.float32) / 16.0
depth = 1.0 / np.maximum(disp, 1e-3) # 단순화된 변환(실제는 초점·baseline 필요)
else:
depth = None
except Exception as e:
print(f'[경고] 3D 처리 실패: {e}')
depth = None
# 6) 시각화/출력
out = img.copy()
for i, (box, score, cid) in enumerate(zip(boxes, scores, cls_ids)):
x1,y1,x2,y2 = box
cv2.rectangle(out, (x1,y1), (x2,y2), (0,255,0), 2)
cv2.putText(out, f'id{cid}:{score:.2f}', (x1, y1-5), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0,255,0), 1)
if masks[i] is not None:
mx,my,mm = masks[i]
roi = out[my:my+mm.shape[0], mx:mx+mm.shape[1]]
color = np.zeros_like(roi); color[:,:,1] = 180
alpha = (mm>0)[:,:,None].astype(np.float32)*0.4
roi[:] = (roi*(1-alpha) + color*alpha).astype(np.uint8)
cv2.imwrite('result.png', out)
print('탐지 개수:', len(boxes), '결과 저장:', 'result.png')
도메인마다 KPI가 다르다
제조 비전 검사는 라인 카메라 입력 → YOLO 결함 탐지 → U-Net 결함 마스크 정밀화 → 스테레오 깊이로 결함 깊이 산정 순서로 흐르고, 미검률 0.5% 미만·위양성 1% 미만·사이클타임 100ms 미만을 KPI로 잡는다.
자율주행·로보틱스는 스트림 입력 → YOLO/Faster R-CNN 다중 클래스 탐지 → U-Net 차선·차도 분할 → SLAM/깊이 융합 경로 계획으로 이어지며, E2E 지연 50ms 미만, mAP 0.45 초과, 차선 mIoU 0.9 초과, ATE 5cm 미만을 기준으로 삼는다.
의료 영상은 장기·병변 탐지를 보조하고 U-Net 세그멘테이션으로 부피·면적을 정량화한 뒤 시계열 변화를 추적하는 흐름이며, 데이터 거버넌스와 성능 재현성, 감사 로그 관리 같은 규제 대응이 함께 따라온다.
AR/VR 디지털 트윈은 실내 스캔 → 객체 탐지 기반 앵커링 → 단안/스테레오 깊이 융합 → 경량 메시 생성으로 진행되고, 추적 드리프트 1%/m 미만, 재구성 Chamfer 거리 최소화, 렌더 FPS 60 이상을 목표로 한다.
통합했을 때 얻는 것과 지켜야 할 것
AMP·TensorRT·배치 최적화를 적용한 실시간 파이프라인은 FPS가 25배 향상되고, 증강·손실 튜닝·ROI 연동을 적용하면 탐지 mAP는 25pt, 분할 mIoU는 38pt 개선된다. 정확한 캘리브레이션과 정규화를 갖추면 3D 깊이 RMSE도 1030% 줄어든다. 정성적으로는 모듈화된 아키텍처 덕분에 기능 교체가 쉬워지고, 관측성과 드리프트 감지로 운영 안정성이 올라가며, 데이터·모델 버전 일관성이 재현성과 규제 대응을 뒷받침한다.
이걸 지속하려면 원천·라벨·캘리브레이션을 별도 버전으로 관리하며 lineage를 추적하고, 개인정보 포함 가능성을 점검해 마스킹이나 온프레미스 저장을 고려해야 한다. 성능·비용 트레이드오프는 YOLO(속도)와 Faster R-CNN(정밀) 사이에서 선택하거나 하이브리드로 운용하는 방식으로 조정하고, U-Net은 해상도를 올릴수록 mIoU는 오르지만 지연도 함께 늘어나므로 패치 추론·타일링으로 타협한다. 서빙 단계에서는 ONNX/TensorRT 엔진 캐싱과 동적 배치, 고정 입력 크기를 채택하고 INT8 양자화 시 교정 세트 품질과 클래스별 드리프트를 점검해야 한다. 임계값 변화에 대한 A/B·회귀 테스트를 자동화하고 실패 케이스를 자동 수집해 세미자동 라벨링과 주기적 재학습 루프로 흘려보내는 체계가 신뢰성을 지탱한다. YOLO 계열이나 NeRF/GSplat 같은 신형 모델이 계속 나오는 만큼 프레임워크·드라이버·런타임 호환성은 사전에 검증해야 한다.
결국 실시간 요구에는 YOLO+U-Net 경량 조합이, 고정밀·복잡 장면에는 Faster R-CNN 보완과 3D 융합이 맞는 선택지다. 탐지·분할·3D를 계층적으로 통합한 설계와 데이터·모델·서빙의 표준화, 관측성 기반 운영 체계가 실무 성능을 좌우한다.