Face Mask Detection using darknet’s YOLOv3
By: Stefanos Kanellopoulos
Tags: Object Detection, Machine Learning, Computer Vision, Covid 19, Deep Learning

Face Mask Detection using darknet’s YOLOv3

COVID-19: Tutorial on how to build a face mask detector using YOLOv3. *For inference, both video streams and images can be used. Stefanos Kanellopoulos Apr 12·9 min read

This article aims to offer complete guidelines (step-by-step) for someone who wants to train an object detector from the YOLO family on custom data. Due to the pandemic, such a task seems to be quite topical.

For this tutorial, I am going to use YOLOv3, one of the most frequently used versions of the YOLO family, which comprises the state-of-the-art object detection system for the real-time scenario and it is amazingly accurate and fast. Newer versions such as YOLOv4, YOLOv5 might achieve even better results, and in my next articles, I am going to also experiment with these architectures and share my findings with you.

Supposing that you already have a grasp of object detection using deep learning techniques and specifically you know the basics about YOLO, let’s dive into our task…

Photo by Anshu A on Unsplash

You can find this project uploaded on my Github repo.

Environment 🌠

In order to implement this project, I exploited Google Colab’s resources. My first experimentations of the pre-processing steps were built on my laptop since they were not computationally expensive, but the model got trained on Colab using GPU.

On Colab via Edit->Notebook Settings someone can activate GPU, Image by author

Dataset 📚

First things first, in order to build a mask detector we need relevant data. Additionally, because of the nature of YOLO, we need annotated data with bounding boxes. One option is to build our own dataset by gathering images either from the web or by taking pictures of friends/acquaintances and annotate them by hand using specific programs such as LabelImg. However, both ideas would be exceptionally tedious and time-consuming (especially the latter). The other option, which is the most viable by far for my purpose, is to use a publically available dataset. I chose Face Mask Detection dataset from Kaggle and I downloaded it directly to my Google Drive (you can check out how to do so here). The downloaded dataset consists of two folders:

images , which comprises 853 .png files

, which comprises 853 .png files annotations, which comprises 853 corresponding .xml annotations.

After we download the dataset, we need to convert the .xml files into .txt and, more precisely, we need to create the YOLO format in order to train our model. An example is shown below:

Assume this is the annotation of an image that contains only 3 bounding boxes (this can be seen from the number of <object> … </object> spans) in .xml format.

To create a .txt file we need 5 things from each .xml file. For each <object> … </object> in an .xml file fetch the class (namely the <name>…</name> field), and the coordinates of the bounding box (namely the 4 attributes in <bndbox>…</bndbox>). The desirable format looks like this:

<class_name> <x_center> <y_center> <width> <height>

However, to achieve that I created a script that fetches the aforementioned 5 attributes for each object in each .xml file and creates the corresponding .txt files. (Note: More analytical steps about the approach of the conversion can be found in my script).

For example, an image1.jpg must have an associated image1.txt containing:

1 0.18359375 0.337431693989071 0.05859375 0.10109289617486339

0 0.4013671875 0.3333333333333333 0.080078125 0.12021857923497267

1 0.6689453125 0.3155737704918033 0.068359375 0.13934426229508196

And this is the exact conversion of the above .xml file into a .txt file. (Note: It is crucial to group into the same folder the images with their corresponding .txt annotations).

Of course, before proceeding with the training we need to be absolutely sure that the conversion was right and we are going to feed our network with valid data. To do so, I created a script that takes an image and its corresponding .txt annotation from a given folder and displays the image with the ground truth bounding boxes. For the above example the image can be shown below:

maksssksksss0.png from Kaggle's publicly available Face Mask Detection dataset

And this is when we know that we are doing well so far, but let’s go on…

Train-Test Split ❇️

In order to train our model and validate it during the training phase, we have to split our data into two sets, the training, and the validation set. The proportion was 90–10% respectively. So I created two new folders and I put 86 images with their corresponding annotations into the test_folder and the rest 767 images into the train_folder.