In this article, we’ll explore the basics of computer vision and build a real-time object detection system using a webcam, Python, OpenCV and YOLO.

Object detection systems are used in many fields: robotics, drones, autonomous vehicles, smart surveillance, industrial sorting and embedded systems. The goal of this tutorial is to understand the fundamentals before moving on to custom-trained models.


Video Demo


Prerequisites

  • A USB or built-in webcam

  • Python installed on your machine

  • Some objects to test detection on

  • The following files:

    • coco.names
    • yolov4-tiny.cfg
    • yolov4-tiny.weights

How does OpenCV work?

OpenCV is an open-source library for computer vision.

It can be used to:

  • read an image or video;
  • access a webcam;
  • modify images;
  • detect shapes;
  • overlay text or rectangles;
  • process images in real time;
  • run AI models.

In this tutorial, OpenCV will:

  1. capture frames from the webcam;
  2. prepare the image for YOLO;
  3. run the detection model;
  4. display detected objects with bounding boxes.

How does YOLO work?

YOLO stands for You Only Look Once.

It’s an AI model based on neural networks that can detect multiple objects in a single image pass. Unlike older methods, YOLO looks at the full image and directly predicts:

  • the object class;
  • its position;
  • its confidence score.

For example, if a person is in front of the camera, YOLO can return:

person: 86%

along with the bounding box coordinates.

In this project we use YOLOv4-tiny — a lightweight version of YOLOv4, faster and better suited for less powerful machines.

Deep learning diagram — convolutional neural network


Setting up the environment

Install Python from the official website:

https://www.python.org/downloads/

Python logo

Then open a terminal in the project folder and install the required libraries:

python -m pip install --upgrade pip
python -m pip install opencv-python
python -m pip install numpy

Your project folder should look like this:

Detection-YOLO/
├── main.py
├── coco.names
├── yolov4-tiny.cfg
└── yolov4-tiny.weights

Commented Python code

import time
import cv2
import numpy as np


CONFIDENCE_THRESHOLD = 0.5
NMS_THRESHOLD = 0.4

MODEL_CONFIG = "yolov4-tiny.cfg"
MODEL_WEIGHTS = "yolov4-tiny.weights"
CLASS_NAMES_FILE = "coco.names"


def load_model():
    with open(CLASS_NAMES_FILE, "r", encoding="utf-8") as file:
        class_names = [line.strip() for line in file if line.strip()]

    network = cv2.dnn.readNetFromDarknet(MODEL_CONFIG, MODEL_WEIGHTS)
    network.setPreferableBackend(cv2.dnn.DNN_BACKEND_OPENCV)
    network.setPreferableTarget(cv2.dnn.DNN_TARGET_CPU)
    output_layers = network.getUnconnectedOutLayersNames()

    return network, output_layers, class_names


def main():
    network, output_layers, class_names = load_model()

    camera = cv2.VideoCapture(0)
    camera.set(cv2.CAP_PROP_FRAME_WIDTH, 640)
    camera.set(cv2.CAP_PROP_FRAME_HEIGHT, 480)
    camera.set(cv2.CAP_PROP_BUFFERSIZE, 1)

    if not camera.isOpened():
        raise RuntimeError("Cannot open camera.")

    previous_time = time.time()

    while True:
        success, frame = camera.read()
        if not success:
            print("Cannot read frame.")
            break

        height, width = frame.shape[:2]

        blob = cv2.dnn.blobFromImage(
            frame,
            scalefactor=1 / 255.0,
            size=(416, 416),
            swapRB=True,
            crop=False,
        )

        network.setInput(blob)
        predictions = network.forward(output_layers)

        boxes = []
        confidences = []
        class_ids = []

        for output in predictions:
            for detection in output:
                scores = detection[5:]
                class_id = int(np.argmax(scores))
                confidence = float(scores[class_id])

                if confidence < CONFIDENCE_THRESHOLD:
                    continue

                center_x = int(detection[0] * width)
                center_y = int(detection[1] * height)
                box_width = int(detection[2] * width)
                box_height = int(detection[3] * height)
                x = center_x - box_width // 2
                y = center_y - box_height // 2

                boxes.append([x, y, box_width, box_height])
                confidences.append(confidence)
                class_ids.append(class_id)

        selected_indices = cv2.dnn.NMSBoxes(
            boxes, confidences, CONFIDENCE_THRESHOLD, NMS_THRESHOLD,
        )

        for index in selected_indices:
            index = int(index)
            x, y, box_width, box_height = boxes[index]
            confidence = confidences[index]
            class_id = class_ids[index]

            x = max(0, x)
            y = max(0, y)

            label = class_names[class_id]
            text = f"{label}: {confidence * 100:.1f}%"

            cv2.rectangle(frame, (x, y), (x + box_width, y + box_height), (0, 255, 0), 2)
            cv2.putText(frame, text, (x, max(25, y - 10)), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 255, 0), 2)

        current_time = time.time()
        fps = 1 / max(current_time - previous_time, 0.001)
        previous_time = current_time

        cv2.putText(frame, f"FPS: {fps:.1f}", (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 0.8, (255, 255, 255), 2)
        cv2.imshow("Object Detection", frame)

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

    camera.release()
    cv2.destroyAllWindows()


if __name__ == "__main__":
    main()

Testing

Once the program is running, a window opens with the live webcam feed.

Place objects in front of the camera:

  • a person;
  • a bottle;
  • a cup;
  • a phone;
  • a chair;
  • a book;
  • a ball.

If the object belongs to the COCO dataset classes, YOLO will draw a bounding box around it with its name and confidence score.


Common issues

The webcam won’t open

Try replacing:

camera = cv2.VideoCapture(0)

with:

camera = cv2.VideoCapture(1)

On Windows you can also try:

camera = cv2.VideoCapture(0, cv2.CAP_DSHOW)

The program is slow

YOLOv4-tiny is lighter than YOLOv4, but detection can still be slow on some machines. You can improve performance by:

  • reducing webcam resolution;
  • closing other applications;
  • using an even lighter model;
  • using a compatible GPU if available.

The object isn’t detected

The model is trained on the COCO dataset and can only recognise classes it has been trained on (person, car, dog, cat, bottle, chair, laptop, cell phone…). Custom objects require a dedicated trained model.


Conclusion

In this tutorial, we used OpenCV and YOLOv4-tiny to detect objects in real time with a webcam.

This is a great introduction to computer vision and lays the groundwork for more advanced projects such as:

  • custom object detection;
  • animal recognition;
  • embedded detection on Raspberry Pi;
  • drone vision;
  • shark detection for the Shark Sentinel project.

In a future article, we’ll go further by training our own YOLO model to detect custom objects in real time.


Files to download


References