Object Detection with YOLO

Implement object detection with YOLO in this hands-on Applied AI engineering tutorial — learn core concepts, step-by-step walkthrough, troubleshooting, and next steps.

Focus: implement object detection with yolo

Sponsored

You’ve trained models, built pipelines, and wrestled with APIs — but when a user uploads an image, how do you actually find the objects in it? Object detection is the backbone of everything from autonomous vehicles to medical imaging, yet most tutorials leave you staring at a notebook with no idea how to turn detection into a real product. By the end of this lesson, you’ll not only run YOLO on your own images but also understand the mental model, the math-lite intuition, and the practical trade-offs that let you implement object detection with yolo like a senior engineer.

The problem this lesson solves

Object detection is deceptively hard. Classification tells you what is in an image, but detection must also answer where — and that requires localizing each object with a bounding box, a confidence score, and often multiple objects per image. Naive approaches like sliding windows are computationally brutal and inaccurate. You need a system that is fast enough for real-time video, accurate enough for production, and simple enough to integrate into a Python application.

Many developers try to build detection from scratch or use outdated models, only to hit memory limits, slow inference, and poor accuracy. The pain is real: you have a computer vision idea, but you can’t get from “it works in a notebook” to “it runs in my API.” This lesson removes that friction by teaching you YOLO — a modern, production-ready family of models — and giving you a replicable implementation pattern.

Core concept / mental model

Think of YOLO as a single pass over the image that predicts all bounding boxes and class probabilities simultaneously. Instead of scanning the image thousands of times, YOLO divides the image into a grid. Each cell is responsible for predicting a fixed number of bounding boxes, each with a confidence score and class probabilities. It’s like a team of scouts looking at a map of a city — each scout (grid cell) reports what they see in their assigned region, and the team fuses all reports into one coherent list of objects.

Key terms you’ll encounter:

  • Bounding box: A rectangle defined by four coordinates (center x, center y, width, height) that encloses an object.
  • Confidence score: A number between 0 and 1 indicating how likely the box contains an object and how accurate the box is.
  • Class probability: The likelihood the object belongs to each pre-defined class (e.g., person, car, dog).
  • Non-max suppression (NMS): A post-processing step that removes duplicate boxes for the same object, keeping only the most confident one.
  • Anchor boxes: Pre-defined box shapes that help the model predict boxes of varying aspect ratios.

YOLO (You Only Look Once) is a family of models: original YOLO, YOLOv5, YOLOv8, and ultralytics’ latest versions. They all share the same core idea — one forward pass, many detections — which makes them orders of magnitude faster than two-stage detectors like R-CNN.

How it works step by step

Implementing object detection with YOLO follows a predictable pipeline. Once you understand these steps, you can apply them to any image, video, or live camera feed.

  1. Install the deep learning framework: For this lesson, we use ultralytics, which ships YOLOv8 and a clean Python API. It depends on PyTorch, so installing it will pull heavy dependencies.
  2. Load a pre-trained model: YOLOv8 comes with several pre-trained weights (e.g., yolov8n.pt for a lightweight model, yolov8s.pt for standard). These weights let you detect 80 common objects (COCO dataset) without any training.
  3. Run inference on an image: Call the model with the image path or numpy array. The model returns a list of detections, each with bounding box coordinates, confidence, and class ID.
  4. Post-process the results: Typically you filter detections by confidence threshold, convert class IDs to human-readable labels, and draw bounding boxes on the image.
  5. Deploy: The same inference call works for video frames and can be wrapped in a function or API endpoint.

The model.predict() method abstracts away grid cells, anchors, and NMS — you don’t need to implement the neural network math. But understanding the pipeline helps you debug and tune performance.

Hands-on walkthrough

Let’s implement a complete object detection script you can run yourself. First, set up a Python environment (Python 3.10+ recommended) and install the necessary package:

pip install ultralytics opencv-python-headless

Pro tip: If you have a GPU, install the CUDA version of PyTorch before ultralytics to get massive speedups during inference. CPU mode works fine for this walkthrough, though.

Now create a Python file detect.py:

from ultralytics import YOLO
import cv2

# Load a pre-trained YOLOv8n model (n = nano, fastest)
model = YOLO('yolov8n.pt')

# Predict on an image (replace 'your_image.jpg')
results = model.predict('your_image.jpg', conf=0.5)

# Results is a list; take the first image
result = results[0]

# Print detections (bounding boxes, confidence, class)
for box in result.boxes:
    x1, y1, x2, y2 = box.xyxy[0].tolist()  # coordinates as integers
    conf = float(box.conf[0])
    cls_id = int(box.cls[0])
    label = model.names[cls_id]
    print(f"{label}: {conf:.2f} at ({int(x1)}, {int(y1)}) to ({int(x2)}, {int(y2)})")

# Draw boxes on the image and save it
annotated = result.plot()  # returns numpy array with boxes drawn
cv2.imwrite('output.jpg', annotated)

Run it with:

python detect.py

Expected output (actual depends on your image):

person: 0.93 at (120, 50) to (340, 400)
car: 0.87 at (500, 200) to (700, 350)
dog: 0.91 at (10, 100) to (220, 300)

You now have a working detector. Let’s build a reusable function for a small batch of images:

from ultralytics import YOLO
from pathlib import Path

model = YOLO('yolov8n.pt')

def detect_objects(image_path: str, conf_threshold: float = 0.5) -> list[dict]:
    """Return a list of detections for a single image."""
    results = model.predict(image_path, conf=conf_threshold, verbose=False)
    detections = []
    for box in results[0].boxes:
        x1, y1, x2, y2 = map(int, box.xyxy[0].tolist())
        detections.append({
            'class': model.names[int(box.cls[0])],
            'confidence': float(box.conf[0]),
            'bbox': [x1, y1, x2, y2]
        })
    return detections

if __name__ == '__main__':
    for img in Path('images').glob('*.jpg'):
        print(img.name, detect_objects(str(img)))

This function is production-friendly: it returns JSON-serializable dicts, respects a confidence threshold, and works with any image. You could drop it into a FastAPI endpoint or a batch processing script.

Compare options / when to choose what

YOLO isn’t your only option, and knowing when to choose it (or a variant) is key. Here’s a comparison of popular approaches as of 2025:

Approach Speed Accuracy Best for Example tools
YOLOv8n (nano) Very fast (~5ms CPU) Good Real-time, edge devices ultralytics
YOLOv8x (xlarge) Slow (~50ms GPU) Excellent High-accuracy offline ultralytics
Faster R-CNN Slow (~200ms GPU) Very high Research, high-precision detectron2
SSD Medium (~30ms GPU) Medium Mobile apps TensorFlow
DETR (transformer) Medium High Complex scenes, no anchors Hugging Face

When to choose what:

  • If you need real-time detection on a laptop or Raspberry Pi, choose a YOLO nano or small variant.
  • If you need maximum accuracy and can wait, choose a larger YOLO model or a two-stage detector like Faster R-CNN.
  • If you’re working with video streams, stick with YOLO because its single-pass architecture keeps up with frame rates.
  • If your objects are small or overlapping, consider DETR or fine-tuning YOLO on your custom dataset.

Pro tip: YOLO models come in sizes (n, s, m, l, x). Start with yolov8n.pt for prototyping, then scale up if accuracy is insufficient.

Troubleshooting & edge cases

1. Missing dependenciesModuleNotFoundError: No module named 'torch'? Install PyTorch first, then ultralytics. Use a virtual environment.

2. Out-of-memory errors on large images — YOLO resizes images automatically, but huge images may consume memory. Downscale before running inference:

result = model.predict('big.jpg', imgsz=640)

3. False positives (low confidence detections) — Raise the conf parameter to 0.7 or 0.8. Also check whether the model is trained on the classes you care about.

4. Class label errors — Ensure you map integer class IDs correctly. The ultralytics model includes model.names, but if you load a custom model, the mapping might differ.

5. Video processing slows down — Use a smaller model and enable half-precision on GPU:

results = model.predict(frame, half=True)

6. Wrong bounding boxes on rotated objects — YOLO outputs axis-aligned boxes. If you need rotated boxes, look for the obb (oriented bounding box) support in newer ultralytics versions.

7. Custom class detection — Pre-trained YOLO only knows 80 COCO classes. To detect custom objects, you must fine-tune on your dataset — see the next step in this track.

What you learned & what's next

In this lesson, you learned how to implement object detection with YOLO: you understand the single-pass mental model, the step-by-step pipeline, and how to write a clean, reusable Python function. You now know how to compare YOLO with other detectors, debug common pitfalls, and choose the right model size for your use case. You can confidently apply this to images, videos, or live streams.

Key points to carry forward:

  • YOLO predicts all boxes and classes in one forward pass — fast and practical.
  • The ultralytics API abstracts away model internals, letting you focus on detection logic.
  • Always filter by confidence and understand class ID mapping.
  • Model size is a trade-off between speed and accuracy.

What’s next: The natural next step in this track is fine-tuning YOLO on custom data. Pre-trained weights are great for common objects, but your production problem almost certainly needs custom classes. In the next lesson, you’ll learn how to prepare a dataset, annotate images, and train your own detector — turning this foundation into a tailored solution.

Practice recap

Try running the detection script on a few images of your own, experimenting with different confidence thresholds (0.3, 0.5, 0.8) and model sizes (nano vs small). Then, modify the function to accept a video file instead of an image, and measure how many frames per second your CPU/GPU can process. This will solidify your understanding of the speed-accuracy trade-off before you move on to fine-tuning.

Common mistakes

  • Skipping the conf threshold and accepting every low-confidence box — leads to many false positives.
  • Using model.names as a fixed list of labels when working with custom-trained models — class IDs may differ.
  • Feeding huge images directly without resizing, causing slowdowns and memory errors; use imgsz to control input size.
  • Forgetting to convert bounding box coordinates from floats to integers before drawing or saving — can cause OpenCV errors.

Variations

  1. Use YOLOv5 through the torch.hub API if you need an older, battle-tested model with a smaller community footprint.
  2. Try the tf (TensorFlow) variant of YOLOv8 for deployment to TensorFlow Serving or mobile via TFLite.
  3. For high-precision, consider a two-stage detector like Faster R-CNN via Detectron2, though it’s slower.

Real-world use cases

  • Real-time pedestrian and vehicle detection in a traffic camera feed to trigger safety alerts.
  • Automated quality control in a factory: detecting defective products on a conveyor belt.
  • Medical imaging assistant: localizing tumors or organs in X-ray scans for review by radiologists.

Key takeaways

  • YOLO performs detection in a single forward pass, making it ideal for real-time applications.
  • The ultralytics library simplifies loading pre-trained models and running inference with just a few lines of Python.
  • Confidence thresholds and class ID mapping are critical to getting clean, usable results.
  • Model size (nano to xlarge) is the primary trade-off between speed and accuracy.
  • With a reusable detection function, you can quickly integrate YOLO into APIs, batch processing, or video streams.
  • Next step: fine-tune YOLO on custom data to detect the specific objects your project needs.

Sponsored

Sponsored

Discussion

Questions, corrections, and tips help everyone reading this page.

0 comments

Add a comment

Shown publicly with your comment.

Be constructive · max 4,000 characters

No comments yet — start the thread.

Related tutorials, quizzes, and articles for this topic.