Object Detection Using Python

CreateImageLabelForTraining.py

import os

import numpy as np 

import pandas as pd

import shutil as sh

from PIL import Image

from tqdm.auto import tqdm


data_path = 'F:/WorkingDirectory_Python/faceIdentify/'

df = pd.read_csv(data_path+'peopleIdentify_csv.csv')

## create x, y, w, h columns 

x, y, w, h = [], [], [], []

for row in df['region_shape_attributes']:

    row = row.replace('{}', '').replace('}', '')

    row = row.split(',')

   # print(row)

    x.append(int(row[1].split(':')[-1]))

    y.append(int(row[2].split(':')[-1]))

    w.append(int(row[3].split(':')[-1]))

    h.append(int(row[4].split(':')[-1]))

## calculating x, y, width and height coordinates

df['x'], df['y'], df['w'], df['h'] = x, y, w, h

## creating a column name image_id having images names as id 

df['image_id'] = [name.split('.')[0] for name in df['filename']]

## creating two columns for storing x and y center values

df['x_center'] = df['x'] + df['w']/2

df['y_center'] = df['y'] + df['h']/2

## define number of classes

#print(df['region_attributes'])

labels = df['region_attributes'].unique()

labels_to_dict = dict(zip(labels, range(0, len(labels))))

print('Lables Directory:', labels_to_dict)

df['classes'] = df['region_attributes']

df.replace({'classes':labels_to_dict}, inplace=True)

df = df[['image_id','x', 'y', 'w', 'h','x_center','y_center','classes']]

## set index of images

index = list(set(df.image_id))



source = 'train'

if True:

    for fold in [0]:

        val_index = index[len(index)*fold//5:len(index)*(fold+1)//5]

        for name,mini in tqdm(df.groupby('image_id')):

            if name in val_index:

                path2save = 'val2017/'

            else:

                path2save = 'train2017/'

            if not os.path.exists(data_path+'convertor/fold{}/labels/'.format(fold)+path2save):

                os.makedirs(data_path+'convertor/fold{}/labels/'.format(fold)+path2save)

            with open(data_path+'convertor/fold{}/labels/'.format(fold)+path2save+name+".txt", 'w+') as f:

                row = mini[['classes','x_center','y_center','w','h']].astype(float).values

                imagename = data_path+"/{}/{}.jpg".format(source,name)

                check_image_width_height = Image.open(imagename)

                img_width, img_height = check_image_width_height.size

                for r in (row):

                    r[1] = r[1]/img_width

                    r[2] = r[2]/img_height

                    r[3] = r[3]/img_width

                    r[4] = r[4]/img_height

                row = row.astype(str)

                for j in range(len(row)):

                    print(row[j], 'n')

                    row[j][0] = str(int(float(row[j][0])))

                    text = ' '.join(row[j])

                    f.write(text)

                    f.write("n")

            if not os.path.exists(data_path+'convertor/fold{}/images/{}'.format(fold,path2save)):


                os.makedirs(data_path+'convertor/fold{}/images/{}'.format(fold,path2save))

            sh.copy(data_path+"/{}/{}.jpg".format(source,name),data_path+'convertor/fold{}/images/{}/{}.jpg'.format(fold,path2save,name))

trainTheExistingModel.py

from ultralytics import YOLO

model = YOLO("yolov8m.pt")

model.train(data="data.yml",epochs=30)

objectdetectorAPIService.py

from ultralytics import YOLO

from flask import request, Response, Flask

from waitress import serve

from PIL import Image

import json


app = Flask(__name__)


@app.route("/")

def root():

    """

    Site main page handler function.

    :return: Content of index.html file

    """

    with open("index.html") as file:

        return file.read()



@app.route("/detect", methods=["POST"])

def detect():

    """

        Handler of /detect POST endpoint

        Receives uploaded file with a name "image_file", 

        passes it through YOLOv8 object detection 

        network and returns an array of bounding boxes.

        :return: a JSON array of objects bounding 

        boxes in format 

        [[x1,y1,x2,y2,object_type,probability],..]

    """

    buf = request.files["image_file"]

    boxes = detect_objects_on_image(Image.open(buf.stream))

    return Response(

      json.dumps(boxes),  

      mimetype='application/json'

    )



def detect_objects_on_image(buf):

    """

    Function receives an image,

    passes it through YOLOv8 neural network

    and returns an array of detected objects

    and their bounding boxes

    :param buf: Input image file stream

    :return: Array of bounding boxes in format 

    [[x1,y1,x2,y2,object_type,probability],..]

    """

    model = YOLO("F:/WorkingDirectory_Python/faceIdentify/runs/detect/train/weights/best.pt")

    results = model.predict(buf)

    result = results[0]

    output = []

    for box in result.boxes:

        x1, y1, x2, y2 = [

          round(x) for x in box.xyxy[0].tolist()

        ]

        class_id = box.cls[0].item()

        prob = round(box.conf[0].item(), 2)

        output.append([

          x1, y1, x2, y2, result.names[class_id], prob

        ])

    return output


serve(app, host='0.0.0.0', port=8080)

ExportModel_PT_To_ONNX

from ultralytics import YOLO


# Load the YOLOv8 model

model = YOLO("best.pt")


# Export the model to ONNX format

model.export(format="onnx")  # creates 'yolov8n.onnx'


# Load the exported ONNX model

onnx_model = YOLO("best.onnx")


# Run inference

results = onnx_model("deepaktest/test4.jpg")

data.yaml

# train and val data as 1) directory: path/images/, 2) file: path/images.txt, or 3) list: [path1/images/, path2/images/]

train: F:\WorkingDirectory_Python\YOLOv8\coco\images\train

val: F:\WorkingDirectory_Python\YOLOv8\coco\images\val

# number of classes

nc: 3

# class names

names: ['person', 'mobile', 'monitor']


index.html


<!DOCTYPE html>

<html lang="en">

<head>

    <meta charset="UTF-8">

    <title>YOLOv8 Object Detection</title>

    <style>

        canvas {

            display:block;

            border: 1px solid black;

            margin-top:10px;

        }

    </style>

</head>

<body>

    <input id="uploadInput" type="file"/>

    <canvas></canvas>

    <script>

       /**

       * "Upload" button onClick handler: uploads selected 

       * image file to backend, receives an array of

       * detected objects and draws them on top of image

       */

       const input = document.getElementById("uploadInput");

       input.addEventListener("change",async(event) => {

           const file = event.target.files[0];

           const data = new FormData();

           data.append("image_file",file,"image_file");

           const response = await fetch("/detect",{

               method:"post",

               body:data

           });

           const boxes = await response.json();

           draw_image_and_boxes(file,boxes);

       })


       /**

       * Function draws the image from provided file

       * and bounding boxes of detected objects on

       * top of the image

       * @param file Uploaded file object

       * @param boxes Array of bounding boxes in format

         [[x1,y1,x2,y2,object_type,probability],...]

       */

       function draw_image_and_boxes(file,boxes) {

          const img = new Image()

          img.src = URL.createObjectURL(file);

          img.onload = () => {

              const canvas = document.querySelector("canvas");

              canvas.width = img.width;

              canvas.height = img.height;

              const ctx = canvas.getContext("2d");

              ctx.drawImage(img,0,0);

              ctx.strokeStyle = "#00FF00";

              ctx.lineWidth = 3;

              ctx.font = "18px serif";

              boxes.forEach(([x1,y1,x2,y2,label]) => {

                  ctx.strokeRect(x1,y1,x2-x1,y2-y1);

                  ctx.fillStyle = "#00ff00";

                  const width = ctx.measureText(label).width;

                  ctx.fillRect(x1,y1,width+10,25);

                  ctx.fillStyle = "#000000";

                  ctx.fillText(label,x1,y1+18);

              });

          }

       }

  </script>  

</body>

</html>