Object Detection with YOLO_v3 and deploying it using Flask and Docker on Kubernetes
I have heard about Yolo Many times but never tried it. Today I wanted to give it a try and see how it performs on images. As I am already in love with Docker I will also Dockerize it and deploy it on Minikube. Hold tight!
First thing first! You will need the following thing to get started. I am giving you links to download.
- Yolo_v3 weights: https://pjreddie.com/media/files/yolov3.weights
- Yolo_v3 cfg file: https://github.com/pjreddie/darknet/tree/master/cfg
- Label file: https://github.com/pjreddie/darknet/blob/master/data/coco.names
If you want to use Yolo_v3 tiny then download and use respective weights and cfg file from here(yolov3-tiny.cfg, yolov3-tiny.weights).
Now let’s get started and write code to use above pre-trained weights for object detection.
Create a python file (let’s say detect.py) and insert the following code to import necessary packages and set the confidence threshold value
Now let’s write some functions to load model and get it ready to do prediction.
Function to get prediction on images is as follows:
Bam!! We are ready to test it. Let’s write our main() function to read an image and detect the objects in it.
At the end insert following code to call the main function
if __name__== "__main__":
main()
You will get a popup window with the detected class and confidence value of the model on your screen. Test it out with a few different images and see how it performs.
Now Let’s expose this model as REST API using flask! Check and install flask for Python 3.X on your system. Now with few changes, you will be able to call this model through API. I am not going into the basics of flask over here. You can find more references for flask here.
Above code will create a flask server on port 5000 (default flask server port) and you can access the model using API “http://localhost:5000/api/test”. to test API use following command:
curl.exe -X POST -F image=@test1.jpg 'http://localhost:5000/api/test' --output test.png
You can check the output of the model in the ‘test.png’ image.
So far So Good! The time has come to use mighty Docker!. Let’s Do It!!!!!!
First install docker as instructed here: (Ubuntu or Windows). I prefer running docker on Linux(Ubuntu). Its a piece of cake to install and run docker on Ubuntu but that’s might not be the case with windows.
To create a docker image from this project first rename your python script file (detect.py) to app.py. It is more convenient to use the main executable script as app.py during building the docker image. Before compiling you will have to list all required packages in a file names ‘requirements.txt’. for this project the requirement.txt will look like this:
Flask
pybase64
jsonpickle
pillow
numpy
opencv-python
Now create a new file named ‘Dockerfile’ and put below code lines into it.
FROM ubuntu:18.04
#MAINTAINER <your name> "<your email>"
RUN apt-get update -y && apt-get install -y python3-pip python3-dev libsm6 libxext6 libxrender-dev
#We copy just the requirements.txt first to leverage Docker cache
COPY ./requirements.txt /app/requirements.txt
WORKDIR /app
RUN pip3 install --upgrade pip
RUN pip3 install -r requirements.txtCOPY . /appENTRYPOINT [ "python3" ]CMD [ "app.py" ]
The project is ready to be compiled with Docker. to compile it with docker run following command from the parent directory of the project.
docker build -t my_yolo:latest .
After successfully building you will get the following message:
Run the newly build docker image by following command:
docker run -d -p 5000:5000 my_yolo:latest
Check the docker images present and the running status of your image.
docker images
docker ps -a
If the status is Up then everything is fine otherwise you can debug using ‘docker log <container id>’ command and see what went wrong.
Now Let’s get to the part to deploy our Docker image to Minikube running locally on Windows 10.
Start Minikube
minikube start
If your Minikube starts fine as shown in the above snapshot then go and grab a bar of chocolate for yourself! I ran into lots of problem with the Minikube and it took almost a day and half to resolve it :(
Now we will go ahead and try to deploy our Docker image with Minikube. First, we will have to start the Minikube docker demon to use docker images present in our system. To start using Docker inside Minikube run the following command:
minikube docker-env
Now to configure our shell, we will have to run the following command:
minikube docker-env | Invoke-Expression
Now your shell is configured to use Minikube’s Docker environment. Go ahead and check the docker images present there. Upon executing command ‘docker images’ you will see Minikube’s repositories with Tag, Image ID, and size.
Now we will have to build our image to run with this Minikube Docker environment. Go to your project directory and build your project with the command mentioned in dockerizing our project section. If you don’t want to build again and if you have already pushed your docker image to some repository like Docker Hub then you can directly pull your image from there and use it.
After successfully building/pull you will be able to see your docker image by using ‘docker images’ command.
Now our image is ready to get deployed! We will use kubectl to run the container and expose it as a service. To start the container run the following command:
kubectl run my-yolov3 --image=chandand/my_yolo --port=8500 --image-pull-policy=IfNotPresent
You will get output as ‘deployment.apps/my-yolov3 created’ on your terminal. You can see that Pod is created by using command:
kubectl get pods
Check the status of Pod. If the status is ‘Running’ then we are good to go ahead and expose it to external traffic using below command:
kubectl expose deployment my-yolov3 --type="LoadBalancer"
Let’s view the service that we’ve just created.
kubectl get services
You can view your Minikube deployment in your web browser! Type following command to start the Minikube dashboard.
minikube dashboard
You can access your flask server API and deployed model in various ways. There are three ways to access app
- Through the Pod IP
- Through the service IP
- Through the Node Port
the best way to access the app is to expose it for external traffic and access it via Node Port.
You can also do a port forwarding to test and debug your API locally. To do port forwarding use following command:
kubectl port-forward my-yolov3-8697b8d9d9-rp79d 5000:5000
Here ‘my-yolov3–8697b8d9d9-rp79d’ is my pod’s complete name. You can use Postman to test your API. The model will be accessible on API ‘http://localhost:5000/api/test’
Hurray!! We have a perfectly working API for Darknet’s YOLO-v3 object detection model deployed on Kubernetes. You must be feeling like this now:
If you want to learn more and get better insight on YOLO, you can go ahead and try to create an app that will use webcam feed as input and detect objects in real-time ( Yeah! you can do real-time object detection with YOLO).
There are a lot of improvements and modifications can be done in this project. If required I will try to write one more blog post about using YOLO on webcam and deploying it on AWS, Azure, Google Cloud or IBM Cloud’s Kubernetes services.
Please share your thoughts in the comment section and give claps if you liked it. Now I will give rest to my overheated and crying PC. See you next time! :)