Object Detection with YOLO_v3 and deploying it using Flask and Docker on Kubernetes

Chandan Dwivedi
Analytics Vidhya
Published in
7 min readSep 27, 2019

--

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.

  1. Yolo_v3 weights: https://pjreddie.com/media/files/yolov3.weights
  2. Yolo_v3 cfg file: https://github.com/pjreddie/darknet/tree/master/cfg
  3. 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.

test.png

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.txt
COPY . /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:

successful build of docker

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
result of command ‘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
Minikube is started!

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.

successful build/pull of docker image in Minikube.

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
Pod created successfully

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
Service is created and exposed as load balancer

You can view your Minikube deployment in your web browser! Type following command to start the Minikube dashboard.

minikube dashboard
Minikube Dashboard

You can access your flask server API and deployed model in various ways. There are three ways to access app

  1. Through the Pod IP
  2. Through the service IP
  3. 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

Testing of API on Postman

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! :)

--

--

Chandan Dwivedi
Analytics Vidhya

AI Engineer. Experienced in developing AI models for Edge devices and deploying them. AI and ML enthusiast with immense interest in DL & self-driving tech.