☀️Siang
Computer Vision

Computer Vision: Object Detection — YOLO, R-CNN, SSD

TOKEN

Panduan lengkap Object Detection — konsep dasar, IoU, NMS, anchor boxes, arsitektur populer (YOLO, R-CNN, SSD), mAP metric, dan implementasi YOLOv8 dengan Ultralytics

Artikel: Cv Object Detection Artikel: Cv Object Detection


1. Pengenalan Object Detection

Object Detection adalah tugas computer vision yang bertujuan untuk tidak hanya mengenali apa objek dalam gambar (klasifikasi), tetapi juga di mana objek tersebut berada (lokalisasi). Outputnya berupa bounding box (kotak pembatas) beserta label kelas dan confidence score untuk setiap objek yang terdeteksi.

Perbedaan Tugas Computer Vision

Diagram: Classification vs Detection vs Segmentation
Classification vs Detection vs Segmentation

Add location

Add pixel mask

🎨 SEGMENTATION

Image → Pixel Mask\n(per-pixel class)

🎯 DETECTION

Image → Bounding Box + Label\n'cat (0.95)'

📊 CLASSIFICATION

Image → Label\n'cat'

Aplikasi Object Detection

Aplikasi Deskripsi Contoh
Mobil OtonomMendeteksi pejalan kaki, kendaraan, rambu lalu lintasTesla Autopilot, Waymo
Surveillance / KeamananMendeteksi orang, aktivitas mencurigakanCCTV pintar, intruder detection
Medical ImagingMendeteksi tumor, lesi, sel abnormalDeteksi kanker dari CT scan
E-commerceVisual product searchCari produk dari foto
ManufakturQuality control, defect detectionDeteksi cacat produk di jalur produksi
PertanianDeteksi hama, penyakit tanamanDrone monitoring pertanian
AR / VRMendeteksi objek real-time untuk augmented realityGoogle Lens, Snapchat filter


2. IoU & Non-Maximum Suppression (NMS)

Intersection over Union (IoU)

IoU adalah metrik untuk mengukur seberapa tumpang tindih antara dua bounding box. IoU digunakan untuk mengevaluasi apakah deteksi benar (true positive) atau salah (false positive).

Diagram: IoU (Intersection over Union)
IoU (Intersection over Union)

Yes

No

Box A\n(Predicted)

IoU = Intersection / Union

Box B\n(Ground Truth)

IoU > 0.5?

✅ True Positive

❌ False Positive

Non-Maximum Suppression (NMS)

Object detector sering menghasilkan banyak bounding box tumpang tindih untuk satu objek. NMS adalah algoritma pasca-pemrosesan yang menghilangkan duplikasi dan hanya menyimpan deteksi terbaik.

Diagram: Non-Maximum Suppression
flowchart TB
    Detect["🔍 Multiple Detections\n(overlapping boxes)"] --> Score["Sort by confidence\nscore"]
    Score --> Pick["Pick highest score\nbox"]
    Pick --> Remove["Remove overlapping\nboxes ("IoU > threshold")"]
    Remove --> Next{"More boxes?"}
    Next -->|Yes| Pick
    Next -->|No| Output["✅ Final Detections"]

    style Detect fill:#2a1f0a,stroke:#f59e0b
    style Score fill:#0f1d3a,stroke:#60a5fa,stroke-width:1.5px
    style Pick fill:#0f2a1f,stroke:#3ecf8e,stroke-width:1.5px
    style Output fill:#0a2a1f,stroke:#34d399,stroke-width:2px
Diagram

Grid Cell

Anchor Box 1\n(wide, short)

Anchor Box 2\n(tall, narrow)

Anchor Box 3\n(square)

IoU with\nGround Truth

Best matching\nanchor selected



4. R-CNN Family: R-CNN → Fast R-CNN → Faster R-CNN

Keluarga R-CNN (Regions with CNN features) adalah pendekatan two-stage untuk object detection: pertama menghasilkan region proposals (kandidat area objek), lalu mengklasifikasi setiap region.

Evolusi R-CNN

Diagram: Evolusi R-CNN → Faster R-CNN
Evolusi R-CNN → Faster R-CNN

2014: R-CNN\nSelective Search\n(~50s/image)

2015: Fast R-CNN\nROI Pooling\n(~2s/image)

2016: Faster R-CNN\nRegion Proposal\nNetwork (RPN)\n(~0.2s/image)

Region Proposal Network (RPN)

Komponen Fungsi
Anchor GeneratorMembuat anchor boxes di setiap posisi feature map
Classification HeadMemprediksi apakah setiap anchor berisi objek (objectness)
Regression HeadMemperbaiki posisi anchor boxes
Proposal LayerMemilih top-N proposals terbaik, lalu NMS


5. YOLO: You Only Look Once

YOLO (Joseph Redmon, 2016) merevolusi object detection dengan pendekatan one-stage — mendeteksi semua objek dalam satu forward pass. YOLO sangat cepat dan cocok untuk real-time applications.

YOLO vs Two-Stage Detectors

Diagram: Two-Stage vs One-Stage (YOLO)
Two-Stage vs One-Stage (YOLO)

ONE-STAGE (YOLO)

Single pass\nthrough network

Predict boxes\n+ classes directly

TWO-STAGE

Stage 1: Region\nProposals

Stage 2: Classify\n+ Refine boxes

Cara Kerja YOLO

Diagram: YOLO Grid System
YOLO Grid System

📷 Input Image\n(416×416)

Divide into S×S grid\n(e.g. 13×13)

Each cell predicts:\n• B bounding boxes\n• Confidence scores\n• Class probabilities

Non-Max Suppression

🎯 Final Detections

Evolusi YOLO

Versi Tahun Keunggulan Kecepatan mAP (COCO)
YOLOv12016One-stage pioneer, sangat cepat45 FPS63.4%
YOLOv22017Batch norm, anchor boxes, multi-scale40 FPS78.6%
YOLOv32018FPN, 3 scale detection, Darknet-5330 FPS84.5%
YOLOv42020CSPDarknet, SPP, PANet62 FPS87.5%
YOLOv52020PyTorch, auto-anchor, easy deploy140 FPS89.2%
YOLOv82023Anchor-free, Ultralytics framework280 FPS92.3%
YOLO112024Arch improvements, efficiency gains300+ FPS93.1%
📌 Catatan Tentang YOLO Versi
  • YOLOv1-v3: Dikembangkan oleh Joseph Redmon (Darknet framework)
  • YOLOv4: Dikembangkan oleh Alexey Bochkovskiy
  • YOLOv5+: Dikembangkan oleh Ultralytics (Python/PyTorch, paling populer saat ini)
  • YOLOv8: Versi terbaru Ultralytics — anchor-free, lebih akurat, API sederhana


6. SSD: Single Shot Detector

SSD (Liu et al., 2016) adalah detektor one-stage lainnya yang mendeteksi objek di multiple scale dari berbagai layer feature map. SSD sangat efisien dan menjadi dasar banyak arsitektur modern.

SSD Multi-Scale Detection

Diagram: SSD Multi-Scale Feature Maps
SSD Multi-Scale Feature Maps

📷 Input Image

Backbone\n(VGG/ResNet)

Feature Map 1\n(38×38)\nSmall objects

Feature Map 2\n(19×19)\nMedium objects

Feature Map 3\n(10×10)\nLarge objects

Detection Head

🎯 Multi-scale\nDetections

Perbandingan: YOLO vs SSD vs Faster R-CNN

Aspek YOLOv8 SSD Faster R-CNN
StageOne-stageOne-stageTwo-stage
Kecepatan★★★ Sangat cepat★★☆ Cepat★☆☆ Lambat
Akurasi (mAP)★★☆ Tinggi★★☆ Cukup tinggi★★★ Sangat tinggi
Objek Kecil★★☆★★☆ Multi-scale helps★★★
Real-time?✅ Ya (30-300+ FPS)✅ Ya (20-60 FPS)⚠️ 5-15 FPS
Edge Deployment✅ Mudah✅ Cukup mudah❌ Sulit
Best ForProduction, real-timeMobile/embeddedResearch, presisi tinggi


7. mAP: Mean Average Precision

mAP (Mean Average Precision) adalah metrik standar untuk mengevaluasi performa object detection. mAP menggabungkan Precision dan Recall ke dalam satu angka yang komprehensif.

Precision & Recall dalam Object Detection

Diagram: TP, FP, FN dalam Object Detection
TP, FP, FN dalam Object Detection

❌ FALSE NEGATIVE (FN)

Object exists\nbut not detected

❌ FALSE POSITIVE (FP)

Detected but\nno object there

✅ TRUE POSITIVE (TP)

Correctly detected\nobject

📊 Metrics:\nPrecision = TP/(TP+FP)\nRecall = TP/(TP+FN)\nmAP = mean Average Precision

mAP Calculation Steps

📐 Langkah Menghitung mAP
  1. Untuk setiap kelas, hitung Precision-Recall curve:
    • Sort semua deteksi berdasarkan confidence (descending)
    • Untuk setiap deteksi, tentukan TP atau FP berdasarkan IoU threshold
    • Akumulasikan TP dan FP → hitung Precision dan Recall pada setiap titik
  2. Average Precision (AP) = Area di bawah PR curve untuk satu kelas
  3. mAP = Rata-rata AP dari semua kelas: mAP = Σ APₖ / K

COCO mAP: Rata-rata mAP pada IoU threshold 0.50, 0.55, 0.60, ..., 0.95 (10 threshold)

Python — Menghitung mAP dari Scratch
import numpy as np

def compute_ap(recalls, precisions):
    """Hitung Average Precision menggunakan interpolation 11-point"""
    # 11-point interpolation (PASCAL VOC style)
    ap = 0.0
    for t in np.arange(0, 1.1, 0.1):
        precisions_at_recall = precisions[recalls >= t]
        if len(precisions_at_recall) > 0:
            ap += np.max(precisions_at_recall)
    return ap / 11.0


def compute_precision_recall(detections, ground_truths, iou_threshold=0.5):
    """
    Hitung precision-recall curve
    
    detections: list of (confidence, bbox, class)
    ground_truths: list of (bbox, class)
    """
    # Sort detections berdasarkan confidence (descending)
    detections = sorted(detections, key=lambda x: x[0], reverse=True)
    
    tp = np.zeros(len(detections))
    fp = np.zeros(len(detections))
    matched_gt = set()
    
    for i, (conf, det_box, det_class) in enumerate(detections):
        best_iou = 0
        best_gt_idx = -1
        
        for j, (gt_box, gt_class) in enumerate(ground_truths):
            if j in matched_gt or det_class != gt_class:
                continue
            iou = compute_iou(det_box, gt_box)
            if iou > best_iou:
                best_iou = iou
                best_gt_idx = j
        
        if best_iou >= iou_threshold:
            tp[i] = 1
            matched_gt.add(best_gt_idx)
        else:
            fp[i] = 1
    
    # Cumulative TP and FP
    tp_cumsum = np.cumsum(tp)
    fp_cumsum = np.cumsum(fp)
    
    precisions = tp_cumsum / (tp_cumsum + fp_cumsum)
    recalls = tp_cumsum / len(ground_truths)
    
    return recalls, precisions


# === CONTOH PERHITUNGAN mAP ===
# Simulated detections: (confidence, [x1,y1,x2,y2], class)
detections = [
    (0.95, [100, 100, 200, 200], 'cat'),
    (0.88, [300, 300, 400, 400], 'dog'),
    (0.82, [110, 105, 205, 210], 'cat'),  # Duplicate detection
    (0.75, [50, 50, 150, 150], 'cat'),    # False positive
    (0.70, [310, 310, 410, 410], 'dog'),
]

# Ground truth: ([x1,y1,x2,y2], class)
ground_truths = [
    ([105, 105, 205, 205], 'cat'),
    ([305, 305, 405, 405], 'dog'),
    ([500, 500, 600, 600], 'dog'),  # Tidak terdeteksi (FN)
]

# Hitung PR curve
recalls, precisions = compute_precision_recall(detections, ground_truths)

print("=== Precision-Recall Analysis ===")
for i, (r, p) in enumerate(zip(recalls, precisions)):
    print(f"  Deteksi {i+1}: P={p:.3f}, R={r:.3f}")

# Hitung AP
ap = compute_ap(recalls, precisions)
print(f"\nAverage Precision (AP): {ap:.3f}")

# mAP = rata-rata AP semua kelas (di sini hanya 1 kelas contoh)
print(f"mAP@0.5: {ap:.3f}")
print("\nDi konteks nyata, hitung AP untuk setiap kelas, lalu rata-rata = mAP")


8. Implementasi: Object Detection dengan YOLOv8

YOLOv8 dari Ultralytics adalah framework paling populer saat ini untuk object detection. API-nya sangat sederhana — hanya beberapa baris kode untuk training, validasi, dan inference.

Python — YOLOv8 Object Detection dengan Ultralytics
# pip install ultralytics
from ultralytics import YOLO
import cv2
import numpy as np

# === 1. INFERENCE DENGAN PRE-TRAINED MODEL ===
# Load model pre-trained di COCO dataset (80 kelas)
model = YOLO('yolov8n.pt')  # 'n'=nano, 's'=small, 'm'=medium, 'l'=large, 'x'=extra-large

# Inference pada gambar
results = model('https://ultralytics.com/images/bus.jpg')

# Parse results
for result in results:
    boxes = result.boxes          # Bounding boxes
    masks = result.masks          # Segmentation masks (jika ada)
    probs = result.probs          # Classification probabilities
    
    print(f"\n=== Deteksi pada gambar ===")
    print(f"Jumlah objek terdeteksi: {len(boxes)}")
    
    for box in boxes:
        # Koordinat bounding box
        x1, y1, x2, y2 = box.xyxy[0].tolist()    # Format (x1, y1, x2, y2)
        confidence = box.conf[0].item()             # Confidence score
        class_id = int(box.cls[0].item())           # Class ID
        class_name = model.names[class_id]          # Class name
        
        print(f"  {class_name}: {confidence:.2f} "
              f"→ [{x1:.0f}, {y1:.0f}, {x2:.0f}, {y2:.0f}]")

# Simpan hasil dengan bounding box
result_plot = results[0].plot()  # Gambar dengan annotated boxes
cv2.imwrite('detection_result.jpg', result_plot)
print("\n✓ Hasil disimpan: detection_result.jpg")

# === 2. VIDEO DETECTION ===
def detect_video(model, video_path, output_path='output.mp4'):
    """Object detection pada video"""
    cap = cv2.VideoCapture(video_path)
    fps = int(cap.get(cv2.CAP_PROP_FPS))
    w = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
    h = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
    
    fourcc = cv2.VideoWriter_fourcc(*'mp4v')
    out = cv2.VideoWriter(output_path, fourcc, fps, (w, h))
    
    frame_count = 0
    while cap.isOpened():
        ret, frame = cap.read()
        if not ret:
            break
        
        # Run YOLOv8 inference
        results = model(frame, verbose=False)
        
        # Draw boxes on frame
        annotated = results[0].plot()
        out.write(annotated)
        
        frame_count += 1
        if frame_count % 30 == 0:
            print(f"  Processed {frame_count} frames...")
    
    cap.release()
    out.release()
    print(f"✓ Video saved: {output_path} ({frame_count} frames)")

# Uncomment untuk proses video:
# detect_video(model, 'input_video.mp4')

# === 3. WEBCAM REAL-TIME DETECTION ===
def detect_webcam(model):
    """Real-time object detection dari webcam"""
    cap = cv2.VideoCapture(0)  # Camera index 0
    
    while True:
        ret, frame = cap.read()
        if not ret:
            break
        
        results = model(frame, verbose=False)
        annotated = results[0].plot()
        
        cv2.imshow('YOLOv8 Real-Time Detection', annotated)
        
        if cv2.waitKey(1) & 0xFF == ord('q'):
            break
    
    cap.release()
    cv2.destroyAllWindows()

# Uncomment untuk webcam:
# detect_webcam(model)

Fine-Tune YOLOv8 pada Custom Dataset

Python — Training YOLOv8 Custom Dataset
from ultralytics import YOLO

# === FINE-TUNE YOLOv8 PADA CUSTOM DATASET ===

# 1. Load pre-trained model (transfer learning)
model = YOLO('yolov8m.pt')  # Start dari pre-trained medium model

# 2. Training dengan custom dataset
# Dataset harus dalam format YOLO:
#   dataset/
#     ├── train/
#     │   ├── images/ (gambar .jpg/.png)
#     │   └── labels/ (label .txt, format: class x_center y_center w h)
#     ├── val/
#     │   ├── images/
#     │   └── labels/
#     └── data.yaml
#
# data.yaml contoh:
#   train: dataset/train/images
#   val: dataset/val/images
#   nc: 3  # jumlah kelas
#   names: ['cat', 'dog', 'bird']  # nama kelas

results = model.train(
    data='dataset/data.yaml',   # Path ke data config
    epochs=100,                 # Jumlah epoch
    imgsz=640,                  # Ukuran gambar input
    batch=16,                   # Batch size
    lr0=0.01,                   # Initial learning rate
    lrf=0.01,                   # Final learning rate (lr0 * lrf)
    warmup_epochs=3,            # Warmup epochs
    optimizer='AdamW',          # Optimizer
    augment=True,               # Data augmentation
    mosaic=1.0,                 # Mosaic augmentation probability
    mixup=0.0,                  # Mixup augmentation
    copy_paste=0.0,             # Copy-paste augmentation
    device=0,                   # GPU device (0, 1, 'cpu')
    project='runs/detect',      # Output directory
    name='custom_model',        # Experiment name
    exist_ok=False,
    pretrained=True,
    verbose=True,
)

# 3. Evaluasi model
metrics = model.val()
print(f"\n=== Hasil Evaluasi ===")
print(f"mAP@50:    {metrics.box.map50:.4f}")
print(f"mAP@50-95: {metrics.box.map:.4f}")
print(f"Precision: {metrics.box.mp:.4f}")
print(f"Recall:    {metrics.box.mr:.4f}")

# 4. Export ke berbagai format
model.export(format='onnx')     # ONNX
model.export(format='torchscript')  # TorchScript
# model.export(format='tflite')  # TensorFlow Lite
# model.export(format='coreml')  # CoreML (iOS)

print("\n✓ Model exported!")
print("  - ONNX: best.onnx")
print("  - TorchScript: best.torchscript")

Menggunakan Pre-trained YOLOv8 untuk Berbagai Tugas

Python — YOLOv8 Multi-Task
from ultralytics import YOLO

# === YOLOv8 UNTUK BERBAGAI TUGAS ===

# 1. OBJECT DETECTION
model_det = YOLO('yolov8n.pt')
results = model_det('image.jpg')

# 2. INSTANCE SEGMENTATION
model_seg = YOLO('yolov8n-seg.pt')
results = model_seg('image.jpg')

# 3. IMAGE CLASSIFICATION
model_cls = YOLO('yolov8n-cls.pt')
results = model_cls('image.jpg')

# 4. POSE ESTIMATION
model_pose = YOLO('yolov8n-pose.pt')
results = model_pose('image.jpg')

# 5. OBB (ORIENTED BOUNDING BOX)
model_obb = YOLO('yolov8n-obb.pt')
results = model_obb('image.jpg')

# === CONTOH: POSE ESTIMATION ===
model_pose = YOLO('yolov8n-pose.pt')
results = model_pose('person.jpg')

for result in results:
    keypoints = result.keypoints
    if keypoints is not None:
        for person_kp in keypoints:
            # 17 COCO keypoints
            # 0=nose, 1=left_eye, 2=right_eye, ...
            # 5=left_shoulder, 6=right_shoulder
            # 11=left_hip, 12=right_hip
            kp_data = person_kp.data[0]  # (17, 3): x, y, confidence
            print(f"Pose keypoints: {kp_data.shape}")
            print(f"  Nose: ({kp_data[0][0]:.0f}, {kp_data[0][1]:.0f})")

print("\n✓ Semua model YOLOv8 siap digunakan!")


9. Quiz Pemahaman

🧠 Quiz: Object Detection

1. Apa perbedaan utama antara Image Classification dan Object Detection?

2. Apa fungsi Non-Maximum Suppression (NMS)?

3. Mengapa YOLO lebih cepat dari Faster R-CNN?

4. Apa itu mAP@0.5 dalam object detection?

5. Apa keunggulan multi-scale detection pada SSD?

🎯 Ringkasan Artikel
  • Object Detection = Klasifikasi + Lokalisasi — mendeteksi "apa" dan "di mana"
  • IoU mengukur overlap antara prediksi dan ground truth
  • NMS menghilangkan deteksi duplikat/tumpang tindih
  • Two-stage (Faster R-CNN): lebih akurat tapi lebih lambat
  • One-stage (YOLO, SSD): sangat cepat, cocok untuk real-time
  • YOLOv8 (Ultralytics) adalah framework paling populer saat ini — mudah digunakan, sangat cepat, multi-task
  • mAP adalah metrik standar evaluasi — rata-rata precision pada berbagai recall threshold
  • Untuk project nyata: mulai dengan YOLOv8 pre-trained, fine-tune pada dataset kustom
🔍 Zoom
100%
🎨 Tema