Complete Ultralytics Tutorial: Object Detection with YOLO

# Tutorial Lengkap Ultralytics: Object Detection dengan YOLO Ultralytics adalah framework Python yang menyediakan implementasi state-of-the-art untuk YOLO (You Only Look Once), salah satu algoritma o...

By Ruby Abdullah · · tutorial
PythonUltralyticsYOLOObject DetectionComputer VisionDeep Learning

Complete Ultralytics Tutorial: Object Detection with YOLO

Ultralytics is a Python framework that provides state-of-the-art implementations for YOLO (You Only Look Once), one of the most popular and efficient object detection algorithms. In this tutorial, we will learn how to use Ultralytics from installation to custom model deployment.

What is Ultralytics and YOLO?

YOLO is a real-time object detection algorithm that can detect multiple objects in a single forward pass of a neural network. Ultralytics provides implementations of YOLOv8, YOLOv9, YOLOv10, and YOLO11 that are easy to use with high performance.

Ultralytics Advantages:
  • Very simple and intuitive API
  • Support for multiple tasks: detection, segmentation, classification, pose estimation
  • Pretrained models for various use cases
  • Easy training and finetuning
  • Export to various formats (ONNX, TensorRT, CoreML, etc.)

Installation

1. Setup Environment

# Create virtual environment

python -m venv ultralyticsenv

source ultralyticsenv/bin/activate # Linux/Mac

ultralyticsenv\Scripts\activate # Windows

Install Ultralytics

pip install ultralytics

For GPU support (CUDA)

pip install torch torchvision --index-url https://download.pytorch.org/whl/cu118

2. Verify Installation

import ultralytics

from ultralytics import YOLO

Check version

print(f"Ultralytics version: {ultralytics.version}")

Check CUDA availability

import torch

print(f"CUDA available: {torch.cuda.isavailable()}")

if torch.cuda.isavailable():

print(f"GPU: {torch.cuda.getdevicename(0)}")

Quick Start: Object Detection

1. Load Pretrained Model

from ultralytics import YOLO

Load YOLOv8 model (available: yolov8n, yolov8s, yolov8m, yolov8l, yolov8x)

n=nano, s=small, m=medium, l=large, x=extra large

model = YOLO('yolov8n.pt') # Model is automatically downloaded

Or load YOLO11 (latest)

model = YOLO('yolo11n.pt')

Model Options:

| Model | Size | mAP | Speed (ms) | Use Case |

|-------|------|-----|------------|----------|

| yolov8n | 3.2M | 37.3 | 1.2 | Edge devices, real-time |

| yolov8s | 11.2M | 44.9 | 1.9 | Balance speed/accuracy |

| yolov8m | 25.9M | 50.2 | 4.1 | General purpose |

| yolov8l | 43.7M | 52.9 | 6.8 | High accuracy |

| yolov8x | 68.2M | 53.9 | 10.8 | Maximum accuracy |

2. Inference on Images

from ultralytics import YOLO

Load model

model = YOLO('yolov8n.pt')

Inference on single image

results = model('path/to/image.jpg')

Inference on multiple images

results = model(['image1.jpg', 'image2.jpg', 'image3.jpg'])

Inference from URL

results = model('https://example.com/image.jpg')

Process results

for result in results:

# Bounding boxes

boxes = result.boxes

print(f"Detected {len(boxes)} objects")

for box in boxes:

# Box coordinates (x1, y1, x2, y2)

xyxy = box.xyxy[0].tolist()

# Confidence score

confidence = box.conf[0].item()

# Class ID and name

classid = int(box.cls[0].item())

classname = model.names[classid]

print(f" {classname}: {confidence:.2f} at {xyxy}")

3. Inference on Video

from ultralytics import YOLO

import cv2

model = YOLO('yolov8n.pt')

Inference on video file

results = model('path/to/video.mp4', stream=True)

for result in results:

# Process each frame

annotatedframe = result.plot()

# Display (optional)

cv2.imshow('Detection', annotatedframe)

if cv2.waitKey(1) & 0xFF == ord('q'):

break

cv2.destroyAllWindows()

4. Real-time Inference from Webcam

from ultralytics import YOLO

import cv2

model = YOLO('yolov8n.pt')

Open webcam

cap = cv2.VideoCapture(0)

while cap.isOpened():

ret, frame = cap.read()

if not ret:

break

# Run inference

results = model(frame, verbose=False)

# Visualize results

annotatedframe = results[0].plot()

# Display FPS

fps = 1000 / results[0].speed['inference']

cv2.putText(annotatedframe, f'FPS: {fps:.1f}', (10, 30),

cv2.FONTHERSHEYSIMPLEX, 1, (0, 255, 0), 2)

cv2.imshow('YOLOv8 Detection', annotatedframe)

if cv2.waitKey(1) & 0xFF == ord('q'):

break

cap.release()

cv2.destroyAllWindows()

Supported Tasks

1. Object Detection

from ultralytics import YOLO

model = YOLO('yolov8n.pt')

results = model('image.jpg')

Access detections

for box in results[0].boxes:

print(f"Class: {model.names[int(box.cls)]}")

print(f"Confidence: {box.conf.item():.2f}")

print(f"Box: {box.xyxy[0].tolist()}")

2. Instance Segmentation

from ultralytics import YOLO

Load segmentation model

model = YOLO('yolov8n-seg.pt')

results = model('image.jpg')

Access masks

for result in results:

if result.masks is not None:

masks = result.masks.data # Tensor of masks

for i, mask in enumerate(masks):

print(f"Mask {i} shape: {mask.shape}")

3. Image Classification

from ultralytics import YOLO

Load classification model

model = YOLO('yolov8n-cls.pt')

results = model('image.jpg')

Access predictions

for result in results:

probs = result.probs

top5indices = probs.top5

top5conf = probs.top5conf

print("Top 5 predictions:")

for idx, conf in zip(top5indices, top5conf):

print(f" {model.names[idx]}: {conf:.2f}")

4. Pose Estimation

from ultralytics import YOLO

Load pose model

model = YOLO('yolov8n-pose.pt')

results = model('image.jpg')

Access keypoints

for result in results:

if result.keypoints is not None:

keypoints = result.keypoints.data # Shape: (numpersons, 17, 3)

for personkpts in keypoints:

print(f"Person keypoints shape: {personkpts.shape}")

# 17 keypoints: nose, eyes, ears, shoulders, elbows, wrists,

# hips, knees, ankles

5. Oriented Bounding Box (OBB)

from ultralytics import YOLO

Load OBB model (for rotated objects)

model = YOLO('yolov8n-obb.pt')

results = model('aerialimage.jpg')

Access oriented boxes

for result in results:

if result.obb is not None:

for obb in result.obb:

# xcenter, ycenter, width, height, rotation

print(f"OBB: {obb.xywhr[0].tolist()}")

Training Custom Model

1. Dataset Preparation

Dataset must be in YOLO format. Folder structure:

dataset/

├── images/

│ ├── train/

│ │ ├── img001.jpg

│ │ ├── img002.jpg

│ │ └── ...

│ └── val/

│ ├── img001.jpg

│ └── ...

├── labels/

│ ├── train/

│ │ ├── img001.txt

│ │ ├── img002.txt

│ │ └── ...

│ └── val/

│ ├── img001.txt

│ └── ...

└── data.yaml

Label Format (YOLO format):

Each .txt file contains annotations:

classid xcenter ycenter width height

All coordinates are normalized (0-1). Example img001.txt:

0 0.5 0.5 0.3 0.4

1 0.2 0.3 0.1 0.2

data.yaml file:
# data.yaml

path: /path/to/dataset

train: images/train

val: images/val

Classes

names:

0: person

1: car

2: bicycle

3: motorcycle

Number of classes

nc: 4

2. Training

from ultralytics import YOLO

Load pretrained model as base

model = YOLO('yolov8n.pt')

Train

results = model.train(

data='data.yaml',

epochs=100,

imgsz=640,

batch=16,

name='mycustommodel',

patience=50, # Early stopping

save=True,

device=0, # GPU 0, or 'cpu'

)

Important Training Parameters:
model.train(

# Data

data='data.yaml',

# Training duration

epochs=100,

patience=50, # Early stopping patience

# Batch and image size

batch=16, # Batch size (-1 for AutoBatch)

imgsz=640, # Image size

# Optimization

optimizer='auto', # SGD, Adam, AdamW, etc.

lr0=0.01, # Initial learning rate

lrf=0.01, # Final learning rate (lr0 * lrf)

momentum=0.937,

weightdecay=0.0005,

# Augmentation

hsvh=0.015, # Hue augmentation

hsvs=0.7, # Saturation augmentation

hsvv=0.4, # Value augmentation

degrees=0.0, # Rotation

translate=0.1,

scale=0.5,

fliplr=0.5, # Horizontal flip probability

mosaic=1.0, # Mosaic augmentation

mixup=0.0, # Mixup augmentation

# Hardware

device=0, # GPU device

workers=8, # Dataloader workers

# Saving

project='runs/train',

name='exp',

save=True,

saveperiod=-1, # Save checkpoint every x epochs

# Resume training

resume=False,

# Pretrained

pretrained=True,

# Validation

val=True,

plots=True,

)

3. Monitor Training

Training progress can be monitored with TensorBoard:

tensorboard --logdir runs/train

Or view results in runs/train/exp/ folder:

  • results.csv - Metrics per epoch
  • results.png - Training curves
  • confusionmatrix.png - Confusion matrix
  • weights/best.pt - Best model weights
  • weights/last.pt - Last epoch weights

4. Model Validation

from ultralytics import YOLO

Load trained model

model = YOLO('runs/train/exp/weights/best.pt')

Validate

metrics = model.val(data='data.yaml')

print(f"mAP50: {metrics.box.map50:.4f}")

print(f"mAP50-95: {metrics.box.map:.4f}")

print(f"Precision: {metrics.box.mp:.4f}")

print(f"Recall: {metrics.box.mr:.4f}")

Fine-tuning and Transfer Learning

1. Fine-tune on Small Dataset

from ultralytics import YOLO

Start from pretrained COCO model

model = YOLO('yolov8n.pt')

Fine-tune with small learning rate

results = model.train(

data='customdata.yaml',

epochs=50,

imgsz=640,

batch=16,

lr0=0.001, # Smaller learning rate

freeze=10, # Freeze first 10 layers

)

2. Transfer Learning from Custom Model

from ultralytics import YOLO

Load custom trained model

model = YOLO('path/to/custommodel.pt')

Continue training on new dataset

results = model.train(

data='newdataset.yaml',

epochs=30,

lr0=0.0001, # Very small LR

)

Export Model

1. Export to Various Formats

from ultralytics import YOLO

model = YOLO('yolov8n.pt')

Export to ONNX

model.export(format='onnx', dynamic=True, simplify=True)

Export to TensorRT (for NVIDIA)

model.export(format='engine', device=0, half=True)

Export to CoreML (for Apple)

model.export(format='coreml')

Export to TFLite (for mobile)

model.export(format='tflite')

Export to OpenVINO (for Intel)

model.export(format='openvino')

Supported Formats:

| Format | Argument | Use Case |

|--------|----------|----------|

| PyTorch | - | Training, development |

| ONNX | onnx | Cross-platform |

| TensorRT | engine | NVIDIA GPU inference |

| CoreML | coreml | iOS/macOS |

| TFLite | tflite | Android, Edge |

| OpenVINO | openvino | Intel hardware |

| NCNN | ncnn | Mobile |

| PaddlePaddle | paddle | Baidu ecosystem |

2. Inference with Exported Model

from ultralytics import YOLO

Load ONNX model

model = YOLO('yolov8n.onnx')

Inference as usual

results = model('image.jpg')

Performance Optimization

1. Batch Inference

from ultralytics import YOLO

model = YOLO('yolov8n.pt')

Batch inference for higher throughput

images = ['img1.jpg', 'img2.jpg', 'img3.jpg', 'img4.jpg']

results = model(images, batch=4)

2. Half Precision (FP16)

from ultralytics import YOLO

model = YOLO('yolov8n.pt')

Inference with FP16

results = model('image.jpg', half=True)

3. Object Tracking

from ultralytics import YOLO

model = YOLO('yolov8n.pt')

Video with tracking

results = model.track(

source='video.mp4',

tracker='bytetrack.yaml', # or 'botsort.yaml'

persist=True, # Persist tracks across frames

stream=True

)

for result in results:

boxes = result.boxes

if boxes.id is not None:

trackids = boxes.id.int().cpu().tolist()

for box, trackid in zip(boxes, trackids):

print(f"Track ID: {trackid}, Class: {model.names[int(box.cls)]}")

Complete Application Examples

1. Object Counting System

from ultralytics import YOLO

import cv2

from collections import defaultdict

model = YOLO('yolov8n.pt')

Track history for each object

trackhistory = defaultdict(lambda: [])

objectcounts = defaultdict(int)

cap = cv2.VideoCapture('traffic.mp4')

Define counting line

liney = 300

while cap.isOpened():

ret, frame = cap.read()

if not ret:

break

# Run tracking

results = model.track(frame, persist=True, verbose=False)

if results[0].boxes.id is not None:

boxes = results[0].boxes.xyxy.cpu().numpy()

trackids = results[0].boxes.id.int().cpu().tolist()

classes = results[0].boxes.cls.int().cpu().tolist()

for box, trackid, cls in zip(boxes, trackids, classes):

x1, y1, x2, y2 = box

centery = (y1 + y2) / 2

# Store track history

track = trackhistory[trackid]

track.append(centery)

# Check if crossed the line

if len(track) > 1:

if track[-2] < liney <= track[-1]:

classname = model.names[cls]

objectcounts[classname] += 1

print(f"Counted: {classname} (Total: {objectcounts[classname]})")

# Draw counting line

cv2.line(frame, (0, liney), (frame.shape[1], liney), (0, 255, 0), 2)

# Draw counts

yoffset = 30

for clsname, count in objectcounts.items():

cv2.putText(frame, f'{clsname}: {count}', (10, yoffset),

cv2.FONTHERSHEYSIMPLEX, 0.7, (0, 255, 0), 2)

yoffset += 25

# Display

annotatedframe = results[0].plot()

cv2.imshow('Counting', annotatedframe)

if cv2.waitKey(1) & 0xFF == ord('q'):

break

cap.release()

cv2.destroyAllWindows()

print("\nFinal counts:")

for clsname, count in objectcounts.items():

print(f" {clsname}: {count}")

2. REST API with FastAPI

from fastapi import FastAPI, File, UploadFile

from fastapi.responses import JSONResponse

from ultralytics import YOLO

import cv2

import numpy as np

from io import BytesIO

from PIL import Image

app = FastAPI()

model = YOLO('yolov8n.pt')

@app.post("/detect")

async def detectobjects(file: UploadFile = File(...)):

# Read image

contents = await file.read()

image = Image.open(BytesIO(contents))

imagenp = np.array(image)

# Run inference

results = model(imagenp)

# Format response

detections = []

for box in results[0].boxes:

detections.append({

"class": model.names[int(box.cls)],

"confidence": float(box.conf),

"bbox": box.xyxy[0].tolist()

})

return JSONResponse(content={

"success": True,

"detections": detections,

"count": len(detections)

})

@app.get("/health")

async def healthcheck():

return {"status": "healthy", "model": "yolov8n"}

Run: uvicorn main:app --host 0.0.0.0 --port 8000

Tips and Best Practices

1. Choosing the Right Model

  • Edge devices (Raspberry Pi, Jetson Nano): yolov8n or yolov8s
  • Desktop/Server with GPU: yolov8m or yolov8l
  • Maximum accuracy: yolov8x
  • Real-time video: yolov8n with TensorRT

2. Improving Accuracy

# Use Test Time Augmentation (TTA)

results = model('image.jpg', augment=True)

Increase input resolution

results = model('image.jpg', imgsz=1280)

Lower confidence threshold for higher recall

results = model('image.jpg', conf=0.1)

3. Debugging

# Verbose output

results = model('image.jpg', verbose=True)

Save results

results = model('image.jpg', save=True, savetxt=True)

Visualize

results[0].show() # Display

results[0].save('output.jpg') # Save

4. Memory Management

import torch

Clear GPU cache

torch.cuda.emptycache()

Limit GPU memory

torch.cuda.setperprocessmemoryfraction(0.5) # Use max 50% GPU memory

Conclusion

Ultralytics provides an easy-to-use framework for object detection and other computer vision tasks. Key takeaways:

  • Simple API: Just a few lines of code for detection, training, and export
  • Multiple tasks: Detection, segmentation, classification, pose estimation
  • Easy training: Fine-tune pretrained models with custom datasets
  • Production ready: Export to various formats for deployment
  • Active development: Regular updates with latest models
  • With Ultralytics, you can quickly build computer vision applications from prototype to production.

    Related Articles

    Florence-2: Microsoft's Multi-Task Vision Foundation Model

    Florence-2: Model Vision Multi-Task dari Microsoft Daftar Isi Pendahuluan Prasyarat Instalasi Memuat Model Florence-2

    Supervision: Computer Vision Toolkit by Roboflow

    Supervision: Toolkit Computer Vision dari Roboflow Dalam proyek computer vision, setelah model mendeteksi objek, Anda ma...

    OpenCV + Deep Learning Tutorial: Modern Image Processing with Python

    OpenCV + Deep Learning: Tutorial Komprehensif Daftar Isi Pendahuluan Prasyarat Dasar-Dasar Preprocessing Gambar [T...

    Complete Guide to DETR: Object Detection with Transformers

    Panduan Lengkap DETR: Object Detection dengan Transformers DETR (DEtection TRansformer) adalah pendekatan revolusioner u...