• 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()