People Counting with OpenCV, Python & Ubidots

Digital Image Processing (DIP) is growing fast, thanks in large part to the increase in available Machine Learning techniques that developers can access via the cloud. Being able to process digital images over the cloud bypasses any dedicated hardware requirements, ultimately making DIP the go-to choice. As the cheapest and most versatile method for processing images, DIP has found wide-ranging applications. One of the most common is pedestrian detection and counting – a useful metric for airports, train stations, retail stores, stadiums, public events, and museums.

Traditional, off-the-shelf people counters aren’t just expensive – the data they generate is often tied to proprietary systems that limit your options for data extraction and KPI optimization. Conversely, an embedded DIP using your own camera and SBC will not only save time and money, but will also give you the freedom to tailor your application to the KPIs you care about, and extract insights from the cloud that wouldn’t otherwise be possible.

Using the cloud to enable your DIP IoT application allows for enhanced overall functionality. With increased capabilities in the form of visualizations, reporting, alerting, and cross-referencing outside data sources (such as weather, live vendor pricing, or business management systems), DIP gives developers the freedom they desire.

Picture a grocer with an ice cream fridge: they want to track the number of people who pass by and select a product, as well as the number of times the door was opened and the internal temperature of the fridge. From just these few data points, a retailer can run correlation analysis to better understand and optimize their product pricing and the fridge’s overall energy consumption.

To begin your digital image processing application, Ubidots has created the following People Counting System tutorial using OpenCV and Python to analyze the number of people in a given area. Expand your applications beyond just people counting with the added resources of Ubidots IoT Development Platform. Here, you can see a real live people counting dashboard built with Ubidots.

In this article, we’ll review how to implement a simple DIP overlay to create a People Counter using OpenCV and Ubidots. This example works best with any Linux-based distribution and also in a Raspberry Pi, Orange Pi or similar embedded systems.

For additional integration inquiries, reach out to Ubidots Support and learn how your business can take advantage of this value-adding technology.

Install Numpy by following the official instructions or just running the command below:

pip install numpy

Install imutils

pip install imutils

Install requests

pip install requests

2) Coding

The whole routine for detection and sending data can be found here. For a better explanation of our coding, we will split the code into eight sections to better explain each aspect of the code for your better understanding.

In Section 1 we import the necessary libraries to implement the our detector, imutils is an useful library tool for DIP and will let us perform different transformations from our results, cv2 is our OpenCV Python wrapper, requests will let us send our data/results over HTTP to Ubidots, and argparse will let us read commands from our command terminal inside our script.

After the library is imported, we will initialize our Histogram Oriented Object descriptor. HOG, for short, this is one of the most popular techniques for object detection and has been implemented in several applications with successful results and, to our fortune, OpenCV has already implemented in an efficient way to combine the HOG algorithm with a support vector machine, or SVM, which is a classic machine learning technique for prediction purposes.

This declaration: cv2.HOGDescriptor_getDefaultPeopleDetector() calls to the pre-trained model for people detection of OpenCV and will feed our support vector machine feature evaluation function.

The detector() function is where the ‘magic’ happens, it receives an RGB image split into three color channels. To avoid performance issues we resize the image using imutils and then call the detectMultiScale() method from our HOG object. The detect-multi-scale method then let’s us analyze the image and know if a person exists using the classification result from our SVM. The parameters of this method are beyond the scope of this tutorial, but if you wish to know more refer to the official OpenCV docs or check out Adrian Rosebrock’s great explanation.

The HOG analysis will generate some capture-boxes (detected objects), but sometimes these boxes are overlapping causing false positives or detection errors. To bypass this confusions we will use the non-maxima suppression utility from the imutils library to remove the overlapping boxes – as displayed below:

Now, in this part of our code, we must define a function to read an image from a local file and detect any persons in it. To accomplish this, you will see that I have simply called the detector() function and added a simple loop to paint the round-boxes for the detector. It returns the number of detected boxes and the image with the painted detection. Then, just simply recreate the result in a new OS window.

Similar to the function of Section 3, this Section 4 function will call the detector() method and paint boxes and the image will be retrieved directly from the webcam using the VideoCapture() method from OpenCV. We have also modified the official OpenCV slightly to get images from the camera and send the results to an Ubidots account every “n” seconds (the sendToUbidots() function will be reviewed later in this tutorial). The function convert_to_base64() will convert your image to a base 64 string, this string is very important for watching our results in Ubidots using JavaScript code inside an HTML Canvas widget.

These two functions of Section 6are the highway for sending your results to Ubidots for understanding and visualizing your data. The first function def buildPayload builds the payload inside the request, while the second function def sendToUbidots receives your Ubidots parameters (TOKEN , the variable, and device labels) to store the results. Which in this case is the length of the detected round-boxes by OpenCV. Optionally, a context can also be sent to store the results as an base64 image so it can be retrieved later.

Now in Section 7, we are reaching the end of our code analysis. The function argsParser() simply parses and returns as a dictionary the arguments passed through your terminal to our script. There will be two arguments within the Parser:

image: The path to the image file inside your system

camera: A variable that if set to ‘true’ will call the cameraDetect() method.

5) Results

In this article, we have explored how to create an IoT People Counter using DIP (image processing), OpenCV, and Ubidots. With these services, your DIP application is far more accurate than PIR or other optical sensors when detecting and identifying the differences between people, places, or things – giving you an efficient people counter without all the static of early data manipulation.

Let us know what you think by leaving Ubidots a comment in our community forums or connect with Ubidots simply with Facebook, Twitter or Hackster.