Building an Image Classifier Running on Raspberry Pi | by Ahmed Gad | Towards Data Science

This tutorial discusses using Raspberry Pi for receiving HTTP requests for classifying images and responding with the classification label. The tutorial starts by building the Physical network connecting Raspberry Pi to the PC via a router. After preparing their IPv4 addresses, SSH session is created for remotely accessing of the Raspberry Pi. After uploading the classification project using FTP, clients can access it using web browsers for classifying images.
Raspberry Pi is a single-board computer designed for being cheap enough so that it is affordable for students in the developing countries. Raspberry Pi supports coding with Python and this is why the term “PI” is available. Raspberry Pi 3 model B is the latest available version. It has a quad-core 1.2 GHz CPU, 1 GB RAM, Wi-Fi, Bluetooth, one HDMI port, 4 USB ports, Ethernet port, camera, and more.
Raspberry Pi comes without an operating system (OS) installed. The OS can be shipped on an SD card which inserted into the SD card slot of the board. The OS can be downloaded using NOOBS (New Out Of the Box Software) (https://www.raspberrypi.org/downloads/noobs) which is an OS manager to easily download and install OSs to Raspberry Pi. The official Raspberry Pi OS is called Raspbian which is a version of Linux designed specifically to Raspberry Pi. It comes with NOOBS. NOOBS also supports a list of OSs to choose from.
After installing the OS in the SD card, next is to run and access it. One way of accessing the Raspberry Pi is by connecting it using the Ethernet interface. Such connection can be direct by connecting it to the Ethernet interface of the PC. Some PCs just have wireless interfaces and not supports Ethernet at all. Others may have problems installing the drivers. For such reason, we can avoid connecting Raspberry Pi to the Ethernet interface of the PC and connect it to one of the Ethernet interfaces in a router. The PC can be connected to such router using Wi-Fi.
Assume that the local area network (LAN) in which the Raspberry Pi and the PC exist uses internet protocol version 4 (IPv4) addresses ranging from 192.168.1.1 to 192.168.1.254. That is the network address is 192.168.1.0 and the subnet mask is 255.255.255.0. Using the dynamic host configuration protocol (DHCP), IPv4 addresses are assigned dynamically to both the PC and the Raspberry Pi. We can easily know the IP address of the PC using ipconfig command in Windows (ifconfig in Linux). According to the following figure, the default gateway is set to 192.168.1.1 and the IPv4 address of the PC is 192.168.1.18.
In order to know the IPv4 address assigned to the Raspberry Pi Ethernet interface, a program called “Advanced IP Scanner” will be used. It can be downloaded from this page https://www.advanced-ip-scanner.com. This program receives a range of IPv4 addresses and searches for the active ones. For each IPv4 address in the range, the program returns its status, hostname, manufacturer, and media access control (MAC) address. Usually, either the hostname or the Manufacturer name of the Raspberry Pi will contain the word “raspberry”. This helps us to determine which IP belongs to the Raspberry Pi. The following figure shows the IPv4 addresses assigned to the gateway interface of the router, PC, and Raspberry Pi Ethernet interface which is signed 192.168.1.19.
As a summary, the following figure shows the 3 devices (Raspberry Pi, router, and PC) in addition to the assigned IPv4 addresses. One Ethernet interface in the router is connected to the Ethernet interface of the Raspberry Pi using a straightforward cable. The router is connected to the PC wirelessly.
After establishing the physical connections, we need to access the Raspberry Pi from the PC. Secure shell (SSH) is a good option. The SSH session can be created using different software programs such as XMing, Putty, and MobaXterm. MobaXterm is an easy-to-use one which is available at this link https://mobaxterm.mobatek.net/download-home-edition.html. The following figure shows the main window of MobaXterm.
IMPORTANT: Before establishing the SSH session, an empty file named “ssh” without extension must be added to the root of the SD card. This is required in order to allow establishing SSH sessions with Raspberry Pi. This is done by inserting the SD card into the PC and adding such file. After inserting the SD card into the Raspberry Pi, we can start creating the SSH session.
The “Session” icon at the top-left of the icon bar is used for establishing sessions such as SSH, Telnet, and others. After clicking on it, the window will be displayed as given in the next figure.
After clicking the left-most SSH icon, MobaXterm asks for either the remote hostname or the IPv4 address of the Raspberry Pi in order to access the remote device. We can use the IPv4 address of the Ethernet interface of the Raspberry Pi which is 192.168.1.19 as given in the following figure.
If the physical connection is working fine, after clicking the “OK” button, you will be asked to login in order to successfully access the remote device. The default login username and password of the Raspberry Pi are:
username: pi
password: raspberry
After entering such details correctly, the session will start successfully according to the following figure. There is just a Raspbian terminal for interacting with the Raspberry Pi OS. Note that MobaXterm allows caching the passwords used in the previous sessions so you do not have to enter the password each time you login.
You might notice that the contents of the SD card are displayed to the left of the terminal. This is because MobaXterm supports creating connections using the file transfer protocol (FTP) for uploading and downloading files. This is a useful feature that saves a lot of time. Without using FTP, we have to eject and insert the SD card multiple times for adding new files to the Raspberry Pi.
To make it easier for beginners to interact with such OS, MobaXterm uses the X11 windowing system which provides a graphical user interface (GUI) to interact with the OS rather than using the command-line. X11 provides a framework for displaying GUI for the Linux operating systems similar to that of Microsoft Windows. We can open the access the GUI using the “startlxde” command as shown in the next figure.
At this time, we have access to the Raspberry Pi using SSH and able to use a GUI for interacting with it. This is wonderful. Using Raspberry Pi that just costs around 50$ we have an interface like what we see in our PCs. Sure it will not support everything in our machines due to the limited memory, SD card storage, and CPU speed.
Next, we can start building the image classifier. The complete classifier is built from scratch in this book “Ahmed Fawzy Gad, Practical Computer Vision Applications Using Deep Learning with CNNs, Apress, 2019, 978–1484241660”.
The classifier is trained using 4 classes from the Fruits 360 dataset. The idea is to use Flask for creating a web application existing in a web server available at Raspberry Pi in which the trained classifier exists. Users can access it for uploading and classifying their own images.
There is a folder named “FruitsApp”, listed in the output of the FTP, which is uploaded previously to the Raspberry Pi. It contains the project files. The project has a main Python file named “flaskApp.py” implementing the Flask application. There are other supplemental HTML, CSS, and JavaScript files for building the interface of the application. In order to run the application, the python “flaskApp.py” file can be executed from the terminal according to the following figure.
The following Python code has the implementation of the Flask application. According to the last line of the code, the application can be accessed using a web browser by visiting the IP address assigned to the Raspberry Pi and port 7777. As a result, the homepage of the application is http://192.168.1.19/7777.
import flask, werkzeug, PIL.Image, numpyapp = flask.Flask(import_name=”FruitsApp”)def extractFeatures():    img = flask.request.files["img"]    img_name = img.filename    img_secure_name = werkzeug.secure_filename(img_name)    img.save(img_secure_name)    print("Image Uploaded successfully.")    img_features = extract_features(image_path=img_secure_name)    print("Features extracted successfully.")    weights_mat = numpy.load("weights.npy")    predicted_label = predict_outputs(weights_mat, img_features, activation="sigmoid")    class_labels = ["Apple", "Raspberry", "Mango", "Lemon"]    predicted_class = class_labels[predicted_label]    return flask.render_template(template_name_or_list="result.html", predicted_class=predicted_class)app.add_url_rule(rule="/extract", view_func=extractFeatures, methods=["POST"], endpoint="extract")def homepage():    return flask.render_template(template_name_or_list="home.html")app.add_url_rule(rule="/", view_func=homepage)app.run(host="192.168.1.19", port=7777, debug=True)
Once the user visits the homepage, an HTML page will be displayed asking for uploading an image. Once an image is uploaded, the “extractFeatures()” function will be called. It extracts the features, predicts the class label, and renders the result in another HTML page according to the following figure. The uploaded image class label is “Apple”. For more details, look at the book in [1].
[1] “Ahmed Fawzy Gad, Practical Computer Vision Applications Using Deep Learning with CNNs, Apress, 2019, 978–1484241660”. It is available at these links: