YOLO Waste Detection Using Python: Build a Real-Time Waste Detection System

Waste management is an important environmental challenge. Identifying and separating waste manually can be time-consuming, especially in large public areas, recycling facilities, factories, and waste collection centers.

Computer vision and artificial intelligence can help automate this process.

In this tutorial, we will build a Waste Detection System using YOLO, Python, and OpenCV. The system can detect different types of waste in images and videos and can be extended to support real-time monitoring and waste classification.

We will cover:

  • What waste detection is

  • How YOLO works

  • Detecting waste in images

  • Real-time waste detection

  • Detecting different waste categories

  • Counting waste objects

  • Creating a custom waste dataset

  • Training a YOLO model

  • Building a waste monitoring system

  • Improving detection accuracy


What Is Waste Detection?

Waste detection is the process of using computer vision to identify waste objects automatically from images or video.

For example, a camera could detect:

Plastic Bottle
Plastic Bag
Can
Paper
Cardboard
Glass Bottle
Food Waste

The AI model identifies each object and places a bounding box around it.

For example:

Plastic Bottle → 94%
Can            → 91%
Paper          → 89%

This information can then be used for waste monitoring, recycling, sorting, or analytics.


Why Use YOLO for Waste Detection?

YOLO is a popular real-time object detection architecture.

For every detected waste object, YOLO can provide:

Class
Confidence
Bounding Box

For example:

Class: plastic_bottle
Confidence: 0.94

Bounding Box:
x1 = 150
y1 = 100
x2 = 310
y2 = 280

YOLO is useful for waste detection because it can process multiple objects in the same image.

For example, one image might contain:

Plastic Bottle
Can
Paper
Cardboard
Glass Bottle

The model can detect them simultaneously.


Waste Detection vs Waste Classification

These two concepts are slightly different.

Waste Classification

Classification answers:

What type of waste is in this image?

For example:

Image
 ↓
Plastic Bottle

Waste Detection

Detection answers:

Where are the waste objects and what type are they?

For example:

Image
 ↓
┌──────────────┐
│ Plastic      │
│ Bottle       │
└──────────────┘

┌──────────┐
│   Can    │
└──────────┘

YOLO performs object detection, making it suitable for scenes containing multiple waste objects.


Example Waste Classes

A waste detection dataset can contain classes such as:

plastic_bottle
plastic_bag
can
paper
cardboard
glass
food_waste
metal

You can choose the classes based on your application.

For a recycling project, you might use:

plastic
paper
metal
glass
organic

For a litter detection project, you could use:

bottle
can
plastic_bag
paper
cup
wrapper

Technologies Used

This project uses:

  • Python

  • YOLO

  • Ultralytics

  • OpenCV

Install the required packages:

pip install ultralytics opencv-python

Create a requirements.txt file:

ultralytics
opencv-python

Install:

pip install -r requirements.txt

Project Structure

A simple project can look like:

yolo-waste-detection/
│
├── images/
│   └── waste.jpg
│
├── videos/
│   └── waste.mp4
│
├── detect_image.py
├── webcam.py
├── detect_video.py
├── count_waste.py
├── train.py
└── requirements.txt

1. Load the YOLO Model

Create:

detect_image.py

Then:

from ultralytics import YOLO

model = YOLO("best.pt")

print("Waste detection model loaded")

Here:

best.pt

should be a model trained to detect the waste categories you need.

A general pretrained YOLO model may recognize common objects such as bottles, but it does not automatically provide every waste-specific category.

For a reliable waste detection system, a custom dataset is recommended.


2. Detect Waste in an Image

Let's start with a simple image detection example.

from ultralytics import YOLO

model = YOLO("best.pt")

results = model("images/waste.jpg")

for result in results:
    result.show()

Run:

python detect_image.py

YOLO will analyze the image and draw bounding boxes around detected waste objects.


3. Get Waste Detection Information

Instead of simply displaying the image, we can access the prediction results.

from ultralytics import YOLO

model = YOLO("best.pt")

results = model("images/waste.jpg")

for result in results:

    for box in result.boxes:

        class_id = int(box.cls[0])
        confidence = float(box.conf[0])

        class_name = result.names[class_id]

        print(
            f"Class: {class_name} | "
            f"Confidence: {confidence:.2f}"
        )

Example output:

Class: plastic_bottle | Confidence: 0.95
Class: can            | Confidence: 0.92
Class: cardboard      | Confidence: 0.89

4. Add a Confidence Threshold

Low-confidence predictions can be ignored.

from ultralytics import YOLO

model = YOLO("best.pt")

results = model(
    "images/waste.jpg",
    conf=0.50
)

for result in results:
    result.show()

Here:

conf=0.50

means predictions below 50% confidence are filtered out.

You can experiment with:

0.30
0.40
0.50
0.60
0.70

The appropriate value depends on your model and environment.


5. Count Waste Objects in an Image

YOLO can also be used to count detected waste objects.

from ultralytics import YOLO

model = YOLO("best.pt")

results = model(
    "images/waste.jpg",
    conf=0.50
)

waste_count = 0

for result in results:

    for box in result.boxes:

        class_id = int(box.cls[0])
        class_name = result.names[class_id]

        if class_name in [
            "plastic_bottle",
            "plastic_bag",
            "can",
            "paper",
            "cardboard"
        ]:
            waste_count += 1

print("Total Waste:", waste_count)

Example:

Total Waste: 17

6. Count Waste by Category

Instead of calculating only the total number of objects, we can count each waste category.

Python's Counter is useful for this.

from collections import Counter
from ultralytics import YOLO

model = YOLO("best.pt")

results = model(
    "images/waste.jpg",
    conf=0.50
)

waste_counts = Counter()

for result in results:

    for box in result.boxes:

        class_id = int(box.cls[0])
        class_name = result.names[class_id]

        waste_counts[class_name] += 1

print(waste_counts)

Example:

Counter({
    'plastic_bottle': 8,
    'can': 5,
    'paper': 3,
    'cardboard': 2
})

This provides a more useful breakdown.


7. Real-Time Waste Detection With Webcam

We can use OpenCV to process a live camera.

Create:

webcam.py

Then:

import cv2
from ultralytics import YOLO

model = YOLO("best.pt")

camera = cv2.VideoCapture(0)

while True:

    success, frame = camera.read()

    if not success:
        break

    results = model(frame)

    annotated_frame = results[0].plot()

    cv2.imshow(
        "Waste Detection",
        annotated_frame
    )

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

camera.release()
cv2.destroyAllWindows()

Run:

python webcam.py

The webcam will display detected waste objects in real time.


8. Display the Current Waste Count

We can show the number of detected waste objects on the screen.

import cv2
from ultralytics import YOLO

model = YOLO("best.pt")

camera = cv2.VideoCapture(0)

while True:

    success, frame = camera.read()

    if not success:
        break

    results = model(
        frame,
        conf=0.50
    )

    waste_count = 0

    for result in results:

        for box in result.boxes:

            waste_count += 1

    annotated_frame = results[0].plot()

    cv2.putText(
        annotated_frame,
        f"Waste Objects: {waste_count}",
        (30, 50),
        cv2.FONT_HERSHEY_SIMPLEX,
        0.8,
        (0, 255, 0),
        2
    )

    cv2.imshow(
        "Waste Monitoring",
        annotated_frame
    )

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

camera.release()
cv2.destroyAllWindows()

The screen might display:

Waste Objects: 12

9. Detect Specific Waste Types

Sometimes we only want to detect a particular category.

For example, we can detect plastic bottles:

from ultralytics import YOLO

model = YOLO("best.pt")

results = model(
    "images/waste.jpg",
    conf=0.50
)

for result in results:

    for box in result.boxes:

        class_id = int(box.cls[0])
        class_name = result.names[class_id]

        if class_name == "plastic_bottle":

            confidence = float(box.conf[0])

            print(
                f"Plastic Bottle Detected: "
                f"{confidence:.2f}"
            )

This can be useful for applications specifically focused on plastic pollution.


10. Waste Detection in a Video

A recorded video can be processed using:

from ultralytics import YOLO

model = YOLO("best.pt")

results = model(
    source="videos/waste.mp4",
    save=True,
    conf=0.50
)

Run the program and YOLO will process the video frame by frame.

The annotated video can then be used for analysis.


11. Why Tracking Is Important for Waste Counting

Suppose a plastic bottle remains visible for 50 frames.

Without tracking:

Frame 1  → Bottle
Frame 2  → Bottle
Frame 3  → Bottle
...
Frame 50 → Bottle

If every detection is counted, the system might report:

50 bottles

when there is actually only one.

Object tracking helps maintain an identity for the same object.

For example:

Frame 1 → Bottle ID 1
Frame 2 → Bottle ID 1
Frame 3 → Bottle ID 1
Frame 4 → Bottle ID 1

Therefore, the application can recognize that these detections belong to the same bottle.


12. Waste Detection With Tracking

YOLO tracking can be enabled using:

from ultralytics import YOLO

model = YOLO("best.pt")

results = model.track(
    source="videos/waste.mp4",
    tracker="bytetrack.yaml",
    save=True,
    conf=0.50
)

The tracker can assign IDs:

Bottle ID: 1
Can ID: 2
Bottle ID: 3
Paper ID: 4

13. Real-Time Waste Tracking

import cv2
from ultralytics import YOLO

model = YOLO("best.pt")

camera = cv2.VideoCapture(0)

while True:

    success, frame = camera.read()

    if not success:
        break

    results = model.track(
        frame,
        persist=True,
        tracker="bytetrack.yaml",
        conf=0.50
    )

    annotated_frame = results[0].plot()

    cv2.imshow(
        "Waste Tracking",
        annotated_frame
    )

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

camera.release()
cv2.destroyAllWindows()

The system can now maintain tracking IDs between frames.


14. Count Unique Waste Objects

We can store tracking IDs using a Python set.

import cv2
from ultralytics import YOLO

model = YOLO("best.pt")

camera = cv2.VideoCapture(0)

unique_objects = set()

while True:

    success, frame = camera.read()

    if not success:
        break

    results = model.track(
        frame,
        persist=True,
        tracker="bytetrack.yaml",
        conf=0.50
    )

    result = results[0]

    if result.boxes.id is not None:

        track_ids = (
            result.boxes.id
            .int()
            .cpu()
            .tolist()
        )

        for track_id in track_ids:
            unique_objects.add(track_id)

    annotated_frame = result.plot()

    cv2.putText(
        annotated_frame,
        f"Objects Seen: {len(unique_objects)}",
        (30, 50),
        cv2.FONT_HERSHEY_SIMPLEX,
        0.8,
        (0, 255, 0),
        2
    )

    cv2.imshow(
        "Waste Counting",
        annotated_frame
    )

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

camera.release()
cv2.destroyAllWindows()

This gives the number of tracking IDs observed during the session.

For crowded scenes, object tracking can occasionally lose or change IDs, so the result should be validated against the actual application requirements.


15. Waste Counting With a Virtual Line

Another useful method is line-crossing detection.

For example, imagine a recycling conveyor:

       Waste Objects
             ↓
             ↓
========================
      COUNTING LINE
========================
             ↓
             ↓
       Sorting Area

When an object crosses the line:

Waste Count += 1

This can be useful for:

  • Recycling plants

  • Conveyor belts

  • Waste collection systems

  • Sorting facilities

  • Smart bins


16. Create a Counting Line

Define:

LINE_Y = 300

Draw it:

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

The line represents the area where an object will be counted.


17. Detect Objects Crossing the Line

We calculate the center of the bounding box:

x1, y1, x2, y2 = map(
    int,
    box.xyxy[0]
)

center_x = (x1 + x2) // 2
center_y = (y1 + y2) // 2

Then compare the object's previous and current positions.

For example:

Previous Y < LINE_Y
Current Y >= LINE_Y

means the object moved across the line.


18. Complete Waste Counting Example

Here is a complete basic line-crossing implementation:

import cv2
from ultralytics import YOLO

model = YOLO("best.pt")

camera = cv2.VideoCapture(0)

LINE_Y = 300

waste_count = 0

previous_positions = {}

counted_ids = set()

while True:

    success, frame = camera.read()

    if not success:
        break

    results = model.track(
        frame,
        persist=True,
        tracker="bytetrack.yaml",
        conf=0.50
    )

    result = results[0]

    if result.boxes.id is not None:

        boxes = (
            result.boxes.xyxy
            .cpu()
            .tolist()
        )

        track_ids = (
            result.boxes.id
            .int()
            .cpu()
            .tolist()
        )

        for box, track_id in zip(
            boxes,
            track_ids
        ):

            x1, y1, x2, y2 = map(
                int,
                box
            )

            center_x = (
                x1 + x2
            ) // 2

            center_y = (
                y1 + y2
            ) // 2

            previous_y = (
                previous_positions
                .get(track_id)
            )

            if (
                previous_y is not None
                and previous_y < LINE_Y
                and center_y >= LINE_Y
                and track_id not in counted_ids
            ):

                waste_count += 1

                counted_ids.add(
                    track_id
                )

            previous_positions[
                track_id
            ] = center_y

    annotated_frame = result.plot()

    cv2.line(
        annotated_frame,
        (0, LINE_Y),
        (
            annotated_frame.shape[1],
            LINE_Y
        ),
        (255, 0, 0),
        2
    )

    cv2.putText(
        annotated_frame,
        f"Waste Count: {waste_count}",
        (30, 50),
        cv2.FONT_HERSHEY_SIMPLEX,
        0.8,
        (0, 255, 0),
        2
    )

    cv2.imshow(
        "Waste Counting",
        annotated_frame
    )

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

camera.release()
cv2.destroyAllWindows()

This counts tracked waste objects when they cross the configured line.


19. Create a Custom Waste Dataset

For accurate waste detection, create a dataset containing the types of waste your application needs to recognize.

For example:

plastic_bottle
plastic_bag
can
paper
cardboard
glass
food_waste

Images should represent real-world conditions.

Include:

Indoor environments
Outdoor environments
Different lighting
Different camera angles
Different object sizes
Overlapping objects
Dirty objects
Partially hidden objects

20. Dataset Structure

A YOLO dataset can be organized like this:

waste-dataset/
│
├── images/
│   ├── train/
│   └── val/
│
├── labels/
│   ├── train/
│   └── val/
│
└── data.yaml

For example:

images/train/waste001.jpg
labels/train/waste001.txt

Each image should have a corresponding label file.


21. Annotate Waste Objects

Every waste object should receive a bounding box.

For example:

Image:
street.jpg

Objects:

plastic_bottle
can
paper

Each object gets its own bounding box.

If there are five bottles, annotate all five bottles individually.

This allows the YOLO model to learn how to detect separate objects.


22. YOLO Label Format

YOLO uses the following format:

class_id center_x center_y width height

For example:

0 0.520 0.430 0.180 0.250

If the dataset uses:

0 → plastic_bottle
1 → can
2 → paper
3 → cardboard

then the label files should use those corresponding class IDs.


23. Create data.yaml

Create:

data.yaml

Example:

path: ./waste-dataset

train: images/train
val: images/val

names:
  0: plastic_bottle
  1: can
  2: paper
  3: cardboard
  4: glass
  5: plastic_bag

The class names must match your annotations.


24. Train the YOLO Waste Detection Model

Create:

train.py

Then:

from ultralytics import YOLO

model = YOLO("yolo11n.pt")

model.train(
    data="data.yaml",
    epochs=50,
    imgsz=640,
    batch=16
)

Run:

python train.py

The model will learn the visual characteristics of the waste categories in your dataset.


25. Train From the Command Line

You can also train using:

yolo detect train \
    data=data.yaml \
    model=yolo11n.pt \
    epochs=50 \
    imgsz=640

A GPU is recommended for faster training.


26. Test the Trained Model

After training, the best model is typically available under the training output directory.

For example:

runs/detect/train/weights/best.pt

Load it:

from ultralytics import YOLO

model = YOLO(
    "runs/detect/train/weights/best.pt"
)

results = model(
    "test_waste.jpg",
    conf=0.50
)

for result in results:
    result.show()

The model should detect the waste categories it was trained on.


27. Waste Classification for Recycling

Waste detection can be combined with classification logic.

For example:

              Waste
                ↓
           YOLO Detection
                ↓
       ┌────────┼────────┐
       ↓        ↓        ↓
    Plastic    Metal    Paper
       ↓        ↓        ↓
   Recycling Recycling Recycling

The detected category can be used to decide which recycling bin or sorting path should receive the object.


28. Smart Waste Sorting

A more advanced system can combine computer vision with physical sorting equipment.

For example:

Camera
   ↓
YOLO Detection
   ↓
Waste Classification
   ↓
Controller
   ↓
Motor / Servo
   ↓
Sorting Bin

Possible categories:

Plastic
Metal
Paper
Glass
Organic

The AI system identifies the object while a controller can activate the appropriate sorting mechanism.


29. Smart Waste Bin

YOLO can also be used in a smart waste bin.

A camera can monitor the waste placed into the bin.

The system can detect:

Plastic
Paper
Can
Glass
Organic Waste

A dashboard could display:

=============================
       SMART WASTE BIN
=============================

Plastic:        42
Paper:          18
Metal:          13
Glass:           7

Total:          80
=============================

This information can be used for waste analytics.


30. Waste Detection Dashboard

A web dashboard can display information collected by the detection system.

For example:

====================================
        WASTE MONITORING
====================================

Total Waste:              1,284

Plastic Bottles:            420
Plastic Bags:               210
Cans:                       185
Paper:                      270
Cardboard:                  120
Glass:                       79

====================================

Additional features could include:

  • Live camera feed

  • Daily waste count

  • Weekly statistics

  • Waste category charts

  • Detection confidence

  • Camera location

  • Detection timestamps


31. Save Detection Data

When a waste object is detected, the application can save information such as:

Timestamp
Waste Type
Confidence
Camera ID
Tracking ID

Example:

from datetime import datetime

detection = {
    "timestamp": datetime.now().isoformat(),
    "camera_id": "CAM-01",
    "waste_type": "plastic_bottle",
    "confidence": 0.94
}

print(detection)

Example output:

{
    'timestamp': '2026-08-10T10:30:25',
    'camera_id': 'CAM-01',
    'waste_type': 'plastic_bottle',
    'confidence': 0.94
}

This data can be stored in a database for analytics.


32. Connect Waste Detection to an API

The Python application can send detection information to a backend server.

import requests

data = {
    "camera_id": "CAM-01",
    "waste_type": "plastic_bottle",
    "confidence": 0.94
}

response = requests.post(
    "https://example.com/api/waste",
    json=data
)

print(response.status_code)

A backend can then store the detection event.

A typical architecture is:

Camera
   ↓
YOLO
   ↓
Waste Detection
   ↓
Python Application
   ↓
Backend API
   ↓
Database
   ↓
Web Dashboard

33. Applications of YOLO Waste Detection

YOLO waste detection can be used in many areas.

Smart Cities

Detect litter in:

Roads
Parks
Public areas
Beaches

Recycling Facilities

Automatically identify waste categories on conveyor belts.

Waste Collection

Monitor the amount and type of waste collected.

Smart Bins

Identify waste placed into intelligent waste containers.

Environmental Monitoring

Detect litter and plastic waste in outdoor environments.

Industrial Waste Management

Monitor waste generated by manufacturing processes.

Beach Cleaning

Detect plastic bottles, bags, cans, and other litter.


34. Challenges in Waste Detection

Waste detection can be challenging because waste objects can have highly variable appearances.

Common problems include:

Object Occlusion

Objects may overlap.

Different Sizes

A bottle near the camera can be much larger than a bottle far away.

Dirty Objects

Waste can be damaged or covered with dirt.

Background Similarity

Some waste objects may have colors similar to their surroundings.

Low Lighting

Night-time or poorly lit scenes can reduce detection accuracy.

Deformed Objects

Plastic bags, paper, and cardboard can have unpredictable shapes.


35. Improve Waste Detection Accuracy

Several techniques can improve the model.

Use a Large Dataset

More diverse training images generally help the model handle different environments.

Include Real-World Images

If your application will monitor streets, train with street images.

If it will monitor a recycling facility, train with recycling-facility images.

Include Difficult Examples

Add images containing:

Overlapping waste
Small objects
Dirty waste
Partially hidden objects
Different lighting
Different backgrounds

Use Data Augmentation

Useful techniques include:

Rotation
Scaling
Cropping
Flipping
Brightness adjustment
Contrast adjustment
Blur

36. Model Evaluation

A waste detection model should be evaluated before deployment.

Important metrics include:

Precision

Measures how many predicted detections are correct.

Precision =
True Positives /
(True Positives + False Positives)

Recall

Measures how many actual waste objects were detected.

Recall =
True Positives /
(True Positives + False Negatives)

IoU

Measures the overlap between predicted and actual bounding boxes.

IoU =
Intersection Area /
Union Area

mAP

Mean Average Precision is commonly used for object detection evaluation.

For waste counting, it is also useful to compare automated counts with manually verified counts.


37. Complete Waste Detection Example

Here is a simple real-time implementation:

import cv2
from ultralytics import YOLO

MODEL_PATH = "best.pt"
CONFIDENCE = 0.50

model = YOLO(MODEL_PATH)

camera = cv2.VideoCapture(0)

while True:

    success, frame = camera.read()

    if not success:
        break

    results = model(
        frame,
        conf=CONFIDENCE
    )

    result = results[0]

    waste_count = len(result.boxes)

    annotated_frame = result.plot()

    cv2.putText(
        annotated_frame,
        f"Waste Objects: {waste_count}",
        (30, 50),
        cv2.FONT_HERSHEY_SIMPLEX,
        0.8,
        (0, 255, 0),
        2
    )

    cv2.imshow(
        "YOLO Waste Detection",
        annotated_frame
    )

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

camera.release()
cv2.destroyAllWindows()

38. Complete Waste Detection Workflow

The complete system can be represented as:

                   CAMERA
                      ↓
                 VIDEO FRAME
                      ↓
                  YOLO MODEL
                      ↓
               WASTE DETECTION
                      ↓
             ┌────────┴────────┐
             ↓                 ↓
        WASTE TYPE          BOUNDING BOX
             ↓                 ↓
             └────────┬────────┘
                      ↓
                 OBJECT TRACKING
                      ↓
                    COUNT
                      ↓
               DATA PROCESSING
                      ↓
                   DATABASE
                      ↓
                WEB DASHBOARD

For a smart recycling system, this can be extended to:

Camera
   ↓
YOLO
   ↓
Waste Detection
   ↓
Classification
   ↓
Tracking
   ↓
Sorting Decision
   ↓
Controller
   ↓
Physical Sorting

Conclusion

YOLO provides a powerful foundation for building automated waste detection systems.

A simple implementation can detect waste objects in images, while a more advanced system can process live camera feeds, track individual objects, count waste, classify different categories, and send detection information to a backend dashboard.

The basic workflow is:

Image / Camera
      ↓
YOLO Detection
      ↓
Waste Classification
      ↓
Object Tracking
      ↓
Counting
      ↓
Analytics

For a reliable production system, the most important component is a high-quality custom dataset that represents the actual environment where the model will be deployed.

With YOLO + Python + OpenCV + Object Tracking, developers can build intelligent applications for smart cities, recycling facilities, waste collection, environmental monitoring, smart bins, and automated waste sorting.

Computer vision can therefore help transform traditional waste management into a more automated, measurable, and data-driven process.