The TensorFlow tutorials are written as Jupyter notebooks and run directly in Google Colab—a hosted notebook environment that requires no setup. Click the Run in Google Colab button.
Colab link - Open colab
Yolov3 Object Detection with Flask and Tensorflow 2.0 (APIs and Detections)
Yolov3 is an algorithm that uses deep convolutional neural networks to perform object detection.
This repository implements Yolov3 using TensorFlow 2.0 and creates two easy-to-use APIs that you can integrate into web or mobile applications.
# yolov3
!mkdir weights
!wget https://pjreddie.com/media/files/yolov3.weights -O weights/yolov3.weights
!wget https://raw.githubusercontent.com/pjreddie/darknet/master/cfg/yolov3.cfg -O weights/yolov3.cfg
!wget https://raw.githubusercontent.com/pjreddie/darknet/master/data/coco.names -O weights/coco.names
Building a simple Keras + deep learning REST API
In this tutorial, we will present a simple method to take a Keras model and deploy it as a REST API.
The examples covered in this post will serve as a template/starting point for building your own deep learning APIs — you will be able to extend the code and customize it based on how scalable and robust your API endpoint needs to be.
Specifically, we will learn: How to (and how not to) load a Keras model into memory so it can be efficiently used for inference
How to use the Flask web framework to create an endpoint for our API
How to make predictions using our model, JSON-ify them, and return the results to the client
How to call our Keras REST API using both cURL and Python
By the end of this tutorial you'll have a good understanding of the components (in their simplest form) that go into a creating Keras REST API.
Feel free to use the code presented in this guide as a starting point for your own deep learning REST API.
Configuring your development environment We'll be making the assumption that Keras is already configured and installed on your machine. If not, please ensure you install Keras using the official install instructions.
From there, we'll need to install Flask (and its associated dependencies), a Python web framework, so we can build our API endpoint. We'll also need requests so we can consume our API as well.
The relevant pip install commands are listed below:
!pip install flask gevent requests pillow
CREATE A Procfile : Create a file with name Procfile and paste content below line in it into it
web: gunicorn app:app
procfile = 'web: gunicorn app:app'
procfiles= open("/content/Procfile","w")
procfiles.write(procfile)
procfiles.close()
INSTALL FLASK AND NGROK
!pip install flask-ngrok
from flask_ngrok import run_with_ngrok
from flask import Flask
Build front end. Build directory structure
!mkdir '/content/templates'
!mkdir '/content/uploads'
!mkdir '/content/detections'
Html_file= open("/content/templates/index.html","w")
Html_file.write(a)
Html_file.close()
Running the Flask App and Using the APIs
Now you can run a Flask application to create two object detections APIs in order to get detections through REST endpoints.
!pip install jsonpickle
# import the necessary packages
import numpy as np
import argparse
import time
import cv2
import os
from flask import Flask, request, Response, jsonify, render_template
import jsonpickle
#import binascii
import io as StringIO
import base64
from io import BytesIO
import io
import json
from PIL import Image
import base64
# construct the argument parse and parse the arguments
confthres = 0.3
nmsthres = 0.1
yolo_path = './'
def get_labels(labels_path):
# load the COCO class labels our YOLO model was trained on
#labelsPath = os.path.sep.join([yolo_path, "yolo_v3/coco.names"])
lpath=os.path.sep.join([yolo_path, labels_path])
LABELS = open(lpath).read().strip().split("\n")
return LABELS
def get_colors(LABELS):
# initialize a list of colors to represent each possible class label
np.random.seed(42)
COLORS = np.random.randint(0, 255, size=(len(LABELS), 3),dtype="uint8")
return COLORS
def get_weights(weights_path):
# derive the paths to the YOLO weights and model configuration
weightsPath = os.path.sep.join([yolo_path, weights_path])
return weightsPath
def get_config(config_path):
configPath = os.path.sep.join([yolo_path, config_path])
return configPath
def load_model(configpath,weightspath):
# load our YOLO object detector trained on COCO dataset (80 classes)
print("[INFO] loading YOLO from disk...")
net = cv2.dnn.readNetFromDarknet(configpath, weightspath)
return net
def image_to_byte_array(image:Image):
imgByteArr = io.BytesIO()
image.save(imgByteArr, format='PNG')
imgByteArr = imgByteArr.getvalue()
return imgByteArr
def get_predection(image,net,LABELS,COLORS):
(H, W) = image.shape[:2]
# determine only the *output* layer names that we need from YOLO
ln = net.getLayerNames()
ln = [ln[i[0] - 1] for i in net.getUnconnectedOutLayers()]
# construct a blob from the input image and then perform a forward
# pass of the YOLO object detector, giving us our bounding boxes and
# associated probabilities
blob = cv2.dnn.blobFromImage(image, 1 / 255.0, (416, 416),
swapRB=True, crop=False)
net.setInput(blob)
start = time.time()
layerOutputs = net.forward(ln)
print(layerOutputs)
end = time.time()
# show timing information on YOLO
print("[INFO] YOLO took {:.6f} seconds".format(end - start))
# initialize our lists of detected bounding boxes, confidences, and
# class IDs, respectively
boxes = []
confidences = []
classIDs = []
# loop over each of the layer outputs
for output in layerOutputs:
# loop over each of the detections
for detection in output:
# extract the class ID and confidence (i.e., probability) of
# the current object detection
scores = detection[5:]
# print(scores)
classID = np.argmax(scores)
# print(classID)
confidence = scores[classID]
# filter out weak predictions by ensuring the detected
# probability is greater than the minimum probability
if confidence > confthres:
# scale the bounding box coordinates back relative to the
# size of the image, keeping in mind that YOLO actually
# returns the center (x, y)-coordinates of the bounding
# box followed by the boxes' width and height
box = detection[0:4] * np.array([W, H, W, H])
(centerX, centerY, width, height) = box.astype("int")
# use the center (x, y)-coordinates to derive the top and
# and left corner of the bounding box
x = int(centerX - (width / 2))
y = int(centerY - (height / 2))
# update our list of bounding box coordinates, confidences,
# and class IDs
boxes.append([x, y, int(width), int(height)])
confidences.append(float(confidence))
classIDs.append(classID)
# apply non-maxima suppression to suppress weak, overlapping bounding
# boxes
idxs = cv2.dnn.NMSBoxes(boxes, confidences, confthres,
nmsthres)
# ensure at least one detection exists
if len(idxs) > 0:
# loop over the indexes we are keeping
for i in idxs.flatten():
# extract the bounding box coordinates
(x, y) = (boxes[i][0], boxes[i][1])
(w, h) = (boxes[i][2], boxes[i][3])
# draw a bounding box rectangle and label on the image
color = [int(c) for c in COLORS[classIDs[i]]]
cv2.rectangle(image, (x, y), (x + w, y + h), color, 2)
text = "{}: {:.4f}".format(LABELS[classIDs[i]], confidences[i])
print(boxes)
print(classIDs)
cv2.putText(image, text, (x, y - 5), cv2.FONT_HERSHEY_SIMPLEX,0.5, color, 2)
return image
labelsPath="weights/coco.names"
cfgpath="weights/yolov3.cfg"
wpath="weights/yolov3.weights"
Lables=get_labels(labelsPath)
CFG=get_config(cfgpath)
Weights=get_weights(wpath)
nets=load_model(CFG,Weights)
Colors=get_colors(Lables)
# Initialize the Flask application
app = Flask(__name__)
run_with_ngrok(app)
@app.route('/')
def home():
return render_template('index.html')
# route http posts to this method
@app.route('/', methods=['POST'])
def main():
# load our input image and grab its spatial dimensions
#image = cv2.imread("/content/rsz_namibia_will_burrard_lucas_wwf_us_1.jpg")
img = request.files["file"].read()
img = Image.open(io.BytesIO(img))
npimg=np.array(img)
image=npimg.copy()
image=cv2.cvtColor(image,cv2.COLOR_BGR2RGB)
res=get_predection(image,nets,Lables,Colors)
image=cv2.cvtColor(image,cv2.COLOR_BGR2RGB)
image=cv2.cvtColor(res,cv2.COLOR_BGR2RGB)
#image=cv2.cvtColor(image,cv2.COLOR_BGR2RGB)
# show the output image
#cv2_imshow(res)
#cv2.waitKey()
#cv2.imwrite("filename.png", res)
np_img=Image.fromarray(image)
img_encoded=image_to_byte_array(np_img)
base64_bytes = base64.b64encode(img_encoded).decode("utf-8")
#return jsonify({'status': True, 'image': image})
return render_template('index.html', user_image=base64_bytes)
# start flask app
if __name__ == '__main__':
app.run()