Text models are everywhere, but many of the most useful real-world problems are visual: counting people, reading signs, catching defects on an assembly line. YOLO object detection in Python is the fastest way to give your code eyes. YOLO (You Only Look Once) takes one look at the whole frame and hands back boxes and labels, quick enough for live video and light enough for a plain CPU.
Think of YOLO like a checkout scanner at a supermarket. The scanner does not study each item for a minute. It glances once, recognises the product, and moves on. YOLO works the same way: one quick look at the whole image, and out come the boxes and labels. That single glance is what makes it fast.
This post is a build project. By the end you will have a working object detection system that finds and labels objects in images and video. We will use the Ultralytics library with YOLO11, a current detection model at the time of writing that runs happily on a plain Central Processing Unit (CPU).
“YOLO changed the game by treating object detection as a single regression problem. One forward pass, all detections.”
Joseph Redmon, YOLO paper
Last Updated: July 2026 | Tested on: Python 3.14.6, ultralytics 8.4.72, PyTorch 2.12.1 (CPU), OpenCV 4.13.0 | Difficulty: Advanced | Reading Time: 15 minutes
- Convolutional Neural Network (CNN) tutorial
- transfer learning tutorial
pip install ultralytics opencv-python(this also pulls in PyTorch automatically)
Object detection is the computer vision task of finding and labeling objects in images and video. Image classification only asks “what is this picture?” and gives back one label. Object detection asks a harder question: “what objects are in here, and where exactly is each one?” It hands you back a box around every object plus a label and a confidence score. YOLO is the most popular approach because it looks at the whole image in a single pass, which is what makes it quick enough for live video.
This post covers how YOLO is put together, how to set up the Ultralytics library, how to run detection on images and video, and how to train the model on your own objects. By the end you will have a working detection system that labels objects in real time.
Whether you are building a security camera, a shelf-stock counter for a shop, or a hobby self-driving car, the patterns in this post are your starting point.
Table of Contents
What We’re Building
The diagram above is the journey a single image takes through YOLO. The image goes in at the top. The backbone pulls out features (edges, shapes, textures). The neck mixes features from different scales so small and large objects both get noticed. The head predicts the boxes and class scores. Non-max suppression (NMS) then throws away duplicate boxes that landed on the same object. What comes out the bottom is a clean list of boxes, labels, and confidence scores.
By the end of this post you will have a Python script that takes any image or webcam frame and draws those boxes for you, with labels and scores. The model recognises 80 everyday categories out of the box (people, cars, dogs, laptops, and so on), and later you will train it on your own custom objects.
The Quick Win: Detection in 5 Lines
No long setup, no config files. We point YOLO at an image and it tells us what is in it. The image below is the sample photo that ships with Ultralytics: a red bus with a few people standing in front of it. The very first time you run this, YOLO quietly downloads the model weights (about 5 MB) and the sample image, then it gets to work.
📄 detect_quick.py: object detection in a handful of lines
from ultralytics import YOLO
# Aditi runs a YOLO detection in just a few lines
model = YOLO("yolo11n.pt") # Nano model: smallest and fastest
results = model("bus.jpg", verbose=False) # Run detection on an image
# Print every detected object
for result in results:
for box in result.boxes:
cls_name = result.names[int(box.cls)]
confidence = float(box.conf)
x1, y1, x2, y2 = map(int, box.xyxy[0])
print(f" {cls_name:>12} ({confidence:.2%}) at [{x1},{y1}]-[{x2},{y2}]")
# Save the annotated image with boxes drawn on it
results[0].save(filename="bus_detected.jpg")
print("\nSaved annotated image to bus_detected.jpg")
▶ Output
bus (94.02%) at [3,229]-[796,728]
person (88.82%) at [671,394]-[809,878]
person (87.83%) at [47,399]-[239,904]
person (85.58%) at [223,408]-[344,860]
person (62.19%) at [0,556]-[68,872]
Saved annotated image to bus_detected.jpg
What happened here: Three real lines of work (load, run, print) and YOLO found five objects: the bus and four people. Each line of output is one detection. The percentage is the model’s confidence, and the four numbers are the corner pixels of the box. Notice the last person sits at only 62 percent confidence: that is the figure half cut off at the edge of the photo, so YOLO is less sure.
The Nano model resizes the image to 640 pixels and runs in a fraction of a second on a plain CPU, faster still on a Graphics Processing Unit (GPU). Your own confidence numbers may shift by a fraction of a percent between library versions, but the objects and rough boxes will match. No training and no config, just load and detect.
YOLO Model Sizes: Speed vs Accuracy
YOLO11 comes in five sizes, from Nano to XLarge. They are the same model wearing different coats: bigger means more accurate but slower. Picking a size is like choosing a vehicle for a delivery. A scooter (Nano) is quick and cheap and perfect for short city hops. A truck (XLarge) carries more and is more thorough, but it is heavier and slower. Most teams land somewhere in the middle. The numbers below come straight from the official Ultralytics docs.
📄 model_comparison.py: choosing the right YOLO11 model
# Anvay compares YOLO11 model sizes (all numbers from the official Ultralytics docs)
models = {
"yolo11n (Nano)": {"params": "2.6M", "mAP": "39.5", "cpu": "56ms", "gpu": "1.5ms", "use_case": "Mobile, edge, real-time video"},
"yolo11s (Small)": {"params": "9.4M", "mAP": "47.0", "cpu": "90ms", "gpu": "2.5ms", "use_case": "Balanced speed and accuracy"},
"yolo11m (Medium)": {"params": "20.1M", "mAP": "51.5", "cpu": "183ms", "gpu": "4.7ms", "use_case": "General production use"},
"yolo11l (Large)": {"params": "25.3M", "mAP": "53.4", "cpu": "239ms", "gpu": "6.2ms", "use_case": "High accuracy needed"},
"yolo11x (XLarge)": {"params": "56.9M", "mAP": "54.7", "cpu": "463ms", "gpu": "11.3ms", "use_case": "Maximum accuracy, batch jobs"},
}
print(f"{'Model':<20} {'Params':>8} {'mAP50-95':>9} {'CPU ms':>8} {'GPU ms':>8} {'Use Case':<35}")
print("=" * 92)
for name, info in models.items():
print(f"{name:<20} {info['params']:>8} {info['mAP']:>9} {info['cpu']:>8} {info['gpu']:>8} {info['use_case']:<35}")
print("\nRule of thumb: start with Nano (n) for prototyping. Move to Medium (m) for production.")
print(" Use XLarge (x) only when the extra accuracy is worth the slower inference.")
▶ Output
Model Params mAP50-95 CPU ms GPU ms Use Case
============================================================================================
yolo11n (Nano) 2.6M 39.5 56ms 1.5ms Mobile, edge, real-time video
yolo11s (Small) 9.4M 47.0 90ms 2.5ms Balanced speed and accuracy
yolo11m (Medium) 20.1M 51.5 183ms 4.7ms General production use
yolo11l (Large) 25.3M 53.4 239ms 6.2ms High accuracy needed
yolo11x (XLarge) 56.9M 54.7 463ms 11.3ms Maximum accuracy, batch jobs
Rule of thumb: start with Nano (n) for prototyping. Move to Medium (m) for production.
Use XLarge (x) only when the extra accuracy is worth the slower inference.
What happened here: The mAP50-95 column (mAP stands for mean Average Precision) is the accuracy score on the COCO (Common Objects in Context) benchmark: higher is better. Notice how little accuracy you gain from Nano to XLarge (39.5 up to 54.7) compared to how much slower it gets (56 ms up to 463 ms on a CPU). The CPU times are Ultralytics’ own measurements on an Intel CPU using ONNX (Open Neural Network Exchange), and the GPU times are on an NVIDIA T4 with TensorRT, so treat them as a guide, not a promise for your exact machine.
For most projects Nano or Medium is the sweet spot. Reach for XLarge only when you have a GPU and accuracy matters more than speed, such as an offline batch job checking thousands of photos overnight.
Real-Time Video Detection
Think of a flipbook: each page is a single still drawing, but flick through them fast enough and your eye sees smooth motion. Video works the same way, so detection on video is just the single-image trick repeated many times per second. OpenCV grabs one frame from the webcam, YOLO runs on that frame, and we draw the boxes before grabbing the next one. Run this on your own laptop with a camera attached, because a webcam loop needs a live camera and a screen, which a server does not have.
📄 video_detection.py: live object detection from a webcam
from ultralytics import YOLO
import cv2
# Aviraj builds a real-time detection pipeline
model = YOLO("yolo11n.pt")
cap = cv2.VideoCapture(0) # 0 = default webcam
print("Starting real-time detection... Press 'q' to quit.")
frame_count = 0
while cap.isOpened():
ret, frame = cap.read()
if not ret:
break
# Run detection
results = model(frame, verbose=False)
annotated = results[0].plot() # Draw boxes on frame
# Count detections
detections = len(results[0].boxes)
cv2.putText(annotated, f"Objects: {detections}", (10, 30),
cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2)
cv2.imshow("YOLO Detection", annotated)
frame_count += 1
if cv2.waitKey(1) & 0xFF == ord("q"):
break
cap.release()
cv2.destroyAllWindows()
print(f"Processed {frame_count} frames")
▶ Output (illustrative: needs a live camera and a display)
Starting real-time detection... Press 'q' to quit. [A live video window opens and draws boxes around detected objects in real time] Processed 847 frames
What happened here: We built a real-time detection loop in about 20 lines. OpenCV grabs each webcam frame, YOLO detects the objects in it, and results[0].plot() draws the boxes onto the frame. We verified the heart of this loop separately (loading a frame, running model(frame), calling .plot(), counting results[0].boxes) and it works on Python 3.14.6. The two parts we cannot show on a server are the live camera feed and the popup window, so the frame count above is representative of a real session, not a captured run.
On a laptop with a GPU, YOLO11 Nano keeps up with 30 to 60 frames per second, which is plenty for a smooth live feed. This is the same pattern behind security cameras, self-driving prototypes, and shop-shelf analytics.
Training YOLO on Custom Data
The built-in model knows 80 everyday objects, but it has never seen a circuit board. To teach it your own objects, you fine-tune: you start from the pre-trained model (which already understands edges, shapes, and textures) and nudge it toward your new labels. This is much like hiring an experienced electrician and showing them your specific wiring, rather than training someone from zero. You need a labeled dataset, a one-line YAML file that points to it, and a single call to model.train().
📄 custom_training.py: train YOLO to detect your own objects
from ultralytics import YOLO
# Anvi trains YOLO to spot defects on circuit boards
# Step 1: describe the dataset in YOLO's simple YAML format
dataset_yaml = """
path: ./circuit-board-dataset
train: images/train
val: images/val
test: images/test
names:
0: good_solder
1: missing_component
2: cold_solder
3: bridge_defect
"""
# Save the dataset config to a file
with open("circuit_board.yaml", "w") as f:
f.write(dataset_yaml)
# Step 2: train, starting from pre-trained weights (transfer learning)
model = YOLO("yolo11m.pt") # Start from the pre-trained Medium model
results = model.train(
data="circuit_board.yaml",
epochs=50,
imgsz=640,
batch=16,
patience=10, # Stop early if it stops improving
device=0, # GPU index, or "cpu" if you have no GPU
project="runs/defect_detection",
name="v1",
)
print("Training complete!")
print(f"Best mAP50: {results.results_dict.get('metrics/mAP50(B)', 'N/A')}")
# Step 3: load the best weights and run on a new board
best_model = YOLO("runs/defect_detection/v1/weights/best.pt")
test_results = best_model("test_board.jpg")
for box in test_results[0].boxes:
cls = test_results[0].names[int(box.cls)]
conf = float(box.conf)
print(f" Detected: {cls} ({conf:.1%})")
▶ Output (illustrative: needs your labeled circuit-board dataset and a GPU)
Training complete! Best mAP50: 0.923 Detected: cold_solder (94.2%) Detected: missing_component (91.7%) Detected: good_solder (98.1%) Detected: good_solder (97.3%)
What happened here: The numbers above are representative of a finished defect-detection run, not a capture from this machine, because a real 50-epoch training needs your own labeled boards and ideally a GPU. The code itself is the genuine current Application Programming Interface (API), though. To prove that, we ran the exact same model.train() call against Ultralytics’ tiny built-in COCO8 dataset (eight images) for one epoch on a CPU with Python 3.14.6, and it trained, validated, saved best.pt, and returned a real results.results_dict whose keys include metrics/mAP50(B), which is the exact key this script reads.
On a proper dataset the same flow gives you a trained detector for your own objects. Two tips that decide success: use at least a few hundred labeled images per class, and set device="cpu" if you do not have a GPU (training will be slow but it will still work).
Common Mistakes
- Too few training images: YOLO needs at least 100 images per class to learn anything useful. For production quality, aim for 1,000 or more per class with varied lighting, angles, and backgrounds.
- Wrong image size: YOLO resizes every image to imgsz (640 by default). If your objects are tiny (a small defect on a big board), bump it up to imgsz=1280. For normal-sized objects, 640 is fine.
- Not using pre-trained weights: Always start from the pre-trained .pt file. Training from scratch needs 10 to 100 times more data and time for a worse result.
- Copying an old model name: Tutorials from a year ago load yolov8n.pt. Use a current model such as yolo11n.pt (or yolo26n.pt) so you get the latest accuracy and speed. The rest of the code stays the same.
Practice Exercises
- Exercise 1: Run YOLO11 on a photo of your own and print every detection with its confidence score.
- Exercise 2: Label 50 to 100 images of one custom object and fine-tune YOLO11 to detect it.
- Exercise 3: Build the full real-time loop: read video frames, run detection on each, and draw the boxes on screen.
More in this series:
- DL: CNNs, Convolution, Pooling, Image Classification
- NLP: Word Embeddings (Word2Vec, GloVe, FastText)
- Deep Learning Capstone: Image Classifier on Hugging Face
Frequently Asked Questions
Do I need a GPU for yolo python detection?
No for running detection: YOLO11 Nano runs detection at 30 or more frames per second on a plain CPU, and a single image takes a fraction of a second. A GPU is strongly recommended for training your own model, where it cuts the job from days to hours. Google Colab gives you free GPU time that is enough for most YOLO training.
Can YOLO detect custom objects?
Yes. The pre-trained model already knows 80 everyday COCO classes. For your own objects you label a dataset (with a tool like Roboflow or LabelImg), write a short YAML config, and fine-tune from the pre-trained weights. With a few hundred labeled images per class you can reach 90 percent or higher mAP, which makes YOLO object detection practical even for niche domains like retail shelves or crop monitoring.
Which YOLO version should I use in 2026?
At the time of writing the Ultralytics docs recommend YOLO11 and the newer YOLO26 (released January 2026). YOLO11 is the safe default: it is well documented, fast, and accurate, and it runs on a plain CPU. YOLO26 adds NMS-free, end-to-end inference and faster edge deployment. Older models like YOLOv8 still work but are no longer the recommended choice. Models change fast, so check the Ultralytics docs for the latest before you start.
What’s Next?
You now know how YOLO is put together (backbone, neck, detection head, and NMS), how to run detection on an image in five lines, how to pick a model size for the speed versus accuracy trade-off, how to loop over webcam frames for real-time video, and how to fine-tune YOLO11 on your own custom objects. That is a complete, production-ready YOLO object detection skill set.
Next, in the multimodal AI tutorial, we go beyond detection to models that can see, hear, and read at the same time. You will send images to an LLM (Large Language Model), transcribe audio with Whisper, and build apps that understand several kinds of input at once.
Want the full picture of how this fits together? Browse every lesson from the basics to advanced AI in the Python + AI/ML tutorial series home.
Interview Questions on YOLO Object Detection
Scenario questions, not trivia: this is the form this topic takes in a real interview.
Q: What is the difference between object detection and image classification?
Image classification answers only “what is this picture?” and returns a single label for the whole image. Object detection answers a harder question: it finds every object, draws a bounding box around each one, and attaches a class label plus a confidence score. So detection gives you both the “what” and the “where,” which is why it can count people or locate defects, while classification cannot.
Q: Why is YOLO called a single-stage detector, and why does that make it fast?
YOLO stands for “You Only Look Once.” It treats detection as one regression problem: a single forward pass through the network predicts all boxes and class scores at once. Older two-stage detectors like Faster R-CNN first propose candidate regions and then classify each one, which is slower. Because YOLO looks at the whole image just once, it is quick enough for live video.
Q: What role does Non-Max Suppression (NMS) play in the pipeline?
The detection head often predicts several overlapping boxes for the same object. NMS cleans this up: it keeps the highest-confidence box, then removes any other box that overlaps it too much (measured by Intersection over Union). Without NMS you would see three or four duplicate boxes stacked on one person. Newer models like YOLO26 offer an NMS-free, end-to-end mode that folds this step into the network itself.
Q: What does the mAP50-95 metric measure, and why is it reported instead of plain accuracy?
mAP means mean Average Precision, averaged across all classes. The “50-95” part means it is averaged over ten IoU thresholds from 0.50 to 0.95, so the model is rewarded for boxes that are tightly aligned, not just roughly on the object. Plain accuracy does not work for detection because there is no single right answer per image: you have to score both whether an object was found and how well the box fits.
Q: Your YOLO model detects large objects well but keeps missing tiny defects on a large image. What do you check first?
Start with the input size. YOLO resizes every image to imgsz (640 by default), which shrinks small objects until they nearly vanish, so raise it to imgsz=1280. If that is not enough, tile the large image into overlapping crops and run detection on each tile, then merge the boxes. Also confirm your training set actually contains enough small-object examples, since the model can only learn what it has seen.
Q: Your real-time webcam loop runs at only 5 FPS on a CPU and feels laggy. How do you speed it up?
First switch to the Nano model (yolo11n.pt) if you were on a larger size, and lower imgsz (say to 480 or 320) to cut the work per frame. Export the model to ONNX or TensorRT for a faster runtime, and move inference to a GPU if one is available. If you still need headroom, process every second or third frame instead of every one, since a webcam feed rarely changes much between adjacent frames.
Go deeper: when you outgrow this post, the official Python documentation is the next stop.
Related Posts
Previous: DL: Transfer Learning with ResNet, VGG Pre-trained Models
Next: NLP: Word Embeddings (Word2Vec, GloVe, FastText)
Series Home: Python + AI/ML Tutorial Series

No comment