Real-time Plastic Bottle Detection with Deep Learning & Python

real-time-plastic-bottle-detection-with-deep-learning-and-opencv-in-python

In this tutorial, I will show you how you can detect a bottle using deep learning (YOLOv8) in Python. Though you can make a bottle detection with custom image processing and shape detection with OpenCV. But to make an accurate bottle detection which you can use for real time, you must use deep learning model.

Before we start, if you are new to computer vision I will suggest you to check out this Udemy course: Python for Computer Vision with OpenCV and Deep Learning.

Now let me break down the entire process of making a plastic bottle detection system into some steps (just for better understanding purpose):

Step1: Download Plastic Bottle Dataset

I think this might be the first step for all projects where we are planning to train or fine-tune a deep learning model with our custom dataset. To correctly choose the right combination of your input dataset for your model, I will suggest you to read this tutorial: How to Choose Images to Train YOLO Model.

For this tutorial, I am going to use “detect Image Dataset” from roboflow. You can download this dataset from this link. This dataset has 35736 images of bottles, especially plastic bottles.

Since I will use YOLOv8 to train our custom bottle detection deep learning model, I am going to download this dataset in YOLOv8 format. To make your training process easier, this dataset comes with Train, Test and Validation set. You can just download and use this, no need to do any modification.

plastic-bottle-detection-dataset-to-train-deep-learning-model-yolo-v8-in-python

After downloading and unzipping this dataset, change this dataset folder name at your convenient. I am giving this dataset folder name as bottle_datasets.

Once you do that, place this dataset folder (bottle_datasets) into your working directory. So now folder structure of your working directory should looks like below:

Woking directory
    ├── bottle_datasets
    	   ├── train
    	   |     ├── images
    	   |     └── labels
    	   ├── test
    	   |     ├── images
    	   |     └── labels
    	   ├── valid
    	   |     ├── images
    	   |     └── labels
    	   └── data.yaml
    

Note: data.yaml file is most important to train our custom YOLOv8 model. This file contains all the information about our training dataset. So please don’t mess with this file.

Step2: Setup Environment

As I said, I am going to use YOLOv8 deep learning model to train our plastic bottle detection model. So we need to configure our system environment according to that.

To set up entire your environment to train YOLO v8 model, please read this tutorial: Train YOLOv8 on Custom dataset in Windows GPU. It will take no more than 5 minutes to install all required libraries. It is always a good practice to create an isolated conda environment for this kind of project.

Also Read:  Realtime Number Plate Detection using Deep Learning

Step3: Train Plastic Bottle Detection Model

After configuring your virtual environment for YOLOv8, create a new Python file or open a Jupyter notebook inside your root working directory. In my case, I am creating a Jupyter notebook. So now my folder structure looks like below:

Woking directory
    ├── bottle_detection.ipynb
    ├── datasets
    	   ├── train
    	   |     ├── images
    	   |     └── labels
    	   ├── test
    	   |     ├── images
    	   |     └── labels
    	   ├── valid
    	   |     ├── images
    	   |     └── labels
    	   └── data.yaml

Now in your Jupyter notebook, first check whether all your configurations are correctly installed or not. To do that, run below Python code.

from IPython import display
display.clear_output()

import ultralytics
ultralytics.checks()
Ultralytics YOLOv8.0.145  Python-3.7.12 torch-1.13.1 CUDA:0 (NVIDIA GeForce GTX 1050 Ti, 4096MiB)
Setup complete  (12 CPUs, 23.8 GB RAM, 107.7/117.9 GB disk)

As you can see in the output, ultralytics library is correctly installed and using GPU (CUDA) as its backend. So now we are ready to train our plastic bottle detection model using YOLOv8. Just run below Python code to train your bottle detection model.

%%time

import os
os.environ['KMP_DUPLICATE_LIB_OK']='True'

from ultralytics import YOLO, settings

# Training dataset path
dataset_path = 'C:/Computer Vision/bottle_datasets'

# Updata global dataset path in ultralytics settings.yaml file
settings.update({'datasets_dir': dataset_path})

# Path to training data.yaml
dataset_yaml = dataset_path+'/data.yaml'

# Load a model
model = YOLO('yolov8n.pt')  # load a pretrained model (recommended for training)

# Train the model
model.train(data=dataset_yaml, epochs=30, imgsz=640, device=0, batch=8)
optimizer: AdamW(lr=0.001667, momentum=0.9) with parameter groups 57 weight(decay=0.0), 64 weight(decay=0.0005), 63 bias(decay=0.0)
Image sizes 640 train, 640 val
Using 8 dataloader workers
Logging results to runs\detect\train
Starting training for 30 epochs...

      Epoch    GPU_mem   box_loss   cls_loss   dfl_loss  Instances       Size
       1/30       1.1G      1.147      2.321       1.49          5        640: 100%|██████████| 1315/1315 [06:09<00:00,
                 Class     Images  Instances      Box(P          R      mAP50  mAP50-95): 100%|██████████| 160/160 [00:
                   all       2557       2752      0.356      0.386      0.297      0.151

      Epoch    GPU_mem   box_loss   cls_loss   dfl_loss  Instances       Size
       2/30      1.12G      1.197      2.025      1.514          7        640: 100%|██████████| 1315/1315 [05:53<00:00,
                 Class     Images  Instances      Box(P          R      mAP50  mAP50-95): 100%|██████████| 160/160 [00:
                   all       2557       2752      0.452      0.427      0.405      0.254

      Epoch    GPU_mem   box_loss   cls_loss   dfl_loss  Instances       Size
       3/30      1.12G      1.159      1.954      1.497          6        640: 100%|██████████| 1315/1315 [05:49<00:00,
                 Class     Images  Instances      Box(P          R      mAP50  mAP50-95): 100%|██████████| 160/160 [00:
                   all       2557       2752      0.451      0.419      0.419      0.257

      Epoch    GPU_mem   box_loss   cls_loss   dfl_loss  Instances       Size
       4/30      1.14G      1.098      1.858      1.448          6        640: 100%|██████████| 1315/1315 [05:48<00:00,
                 Class     Images  Instances      Box(P          R      mAP50  mAP50-95): 100%|██████████| 160/160 [00:
                   all       2557       2752      0.648      0.546      0.624      0.409

      Epoch    GPU_mem   box_loss   cls_loss   dfl_loss  Instances       Size
       5/30      1.14G      1.054      1.745      1.417          8        640: 100%|██████████| 1315/1315 [05:47<00:00,
                 Class     Images  Instances      Box(P          R      mAP50  mAP50-95): 100%|██████████| 160/160 [00:
                   all       2557       2752      0.655      0.531      0.601      0.414
.....
.....
.....

Line 3 & 4 is to avoid this error:

OMP: Error #15: Initializing libiomp5md.dll, but found libiomp5md.dll already initialized.
OMP: Hint This means that multiple copies of the OpenMP runtime have been linked into the program. That is dangerous, since it can degrade performance or cause incorrect results. The best thing to do is to ensure that only a single OpenMP runtime is linked into the process, e.g. by avoiding static linking of the OpenMP runtime in any library. As an unsafe, unsupported, undocumented workaround you can set the environment variable KMP_DUPLICATE_LIB_OK=TRUE to allow the program to continue to execute, but that may cause crashes or silently produce incorrect results.

In line 9, I am defining my bottle detection dataset (bottle_datasets) folder path.

Also Read:  Beginners Guide to LiDAR: Light Detection and Ranging

In line 12, I am updating global dataset path of ultralytics. To do that you need to change or update dataset path in settings.yaml. Otherwise, you may get below error while running YOLOv8 model for any other project or dataset:

RuntimeError: Dataset 'bottle_datasets/data.yaml' error  
Dataset 'bottle_datasets/data.yaml' images not found , missing path 'C:\Computer Vision\bottle_datasets\valid\images'
Note dataset download directory is 'D:\Computer Vision\Car Number plate\datasets'. You can update this in 'C:\Users\Anindya\AppData\Roaming\Ultralytics\settings.yaml'

This error occurred because, in my last project for the first time I configured YOLO v8 environment and trained car number plate detection model. On that time a settings.yaml file generated (inside this directory: C:\Users\Anindya\AppData\Roaming\Ultralytics\settings.yaml). This settings.yaml file looks like below:

settings_version: 0.0.4
datasets_dir: D:\Computer Vision\Car Number plate\datasets
weights_dir: weights
runs_dir: runs
uuid: c4cec302062e239598045f77d3d082533c84e0ff2908ec99ef8362c428d76f76
sync: true
api_key: ''
clearml: true
comet: true
dvc: true
hub: true
mlflow: true
neptune: true
raytune: true
tensorboard: true
wandb: true

The root cause of this issue is this settings.yaml file generated by Ultralytics. It gets created when you run YOLOv8 for the first time and assumes that all the time you will run YOLOv8 model, you dataset folder should be same as per the first project.

So to avoid this error, you need to modify datasets_dir path in this settings.yaml file. I tried changing this path manually, but it was not working. When I tried with this line of code (line 12), it works for me.

I have used 30 epochs to train my bottle detector YOLOv8 model, you can also try different numbers. If you have any issues understanding the above code, I will suggest you to first read below listed tutorials:

After successfully training your custom dataset with the YOLOv8 model, a ‘runs‘ folder will be generated within your current working directory. The ‘best.pt’ file represents your final trained YOLOv8 model. So now your folder structure should looks like below:

Woking directory
	├── runs
	|    └── detect
	|         └── train
	|              ├── Some statistical images
	|              └── weights
	|                   ├── best.pt
        |	            └── last.pt
	|
        ├── datasets
        |	 ├── train
        |	 |     ├── images
        |	 |     └── labels
        |	 ├── test
        |	 |     ├── images
        |	 |     └── labels
        |	 ├── valid
        |	 |     ├── images
        |	 |     └── labels
        |	 └── data.yaml
	└── bottle_detection.ipynb

Step4: Test on New Image

So we are ready with our trained bottle detection deep learning model (YOLOv8). Let’s now test how our custom mode is detecting bottle in a new image.

from ultralytics import YOLO
 
# Load our custom bottle detection deep learning model
model = YOLO("runs/detect/train/weights/best.pt")
 
# Use the model to detect object - plastic bottle
model.predict(source="input_image_5.jpg", save=True, show=True)
plastic-bottle-detection-with-deep-learning-and-opencv-in-python

You can find output image inside runs -> detect -> predict folder. As you can see in the above output, our model is correctly detecting plastic bottles from our input image.

Also Read:  Real-time Face Detection using Python & OpenCV

Step5: Test on Realtime Video

So we have seen that our model is correctly working for input image, let’s now see how our custom plastic bottle detection deep learning model (YOLO v8) is performing on real-time video.

# For video
from ultralytics import YOLO
 
# Load custom trained YOLOv8 model
model = YOLO("runs/detect/train/weights/best.pt")
 
# Use the model to detect object
model.predict(source="test_video_4.mp4", show=True)

Just to Say

In this tutorial, I made a simple real-time plastic bottle detection system by training YOLOv8 deep learning model in Python. This type of project can be applied to the production or manufacturing company. For example counting bottle, bottle cap is open or not, bottle is filed or not etc.

This is it for this tutorial. If you are new to computer vision I will suggest you to check out this Udemy course: Python for Computer Vision with OpenCV and Deep Learning.

Similar Read:

Leave a comment