├── README.md └── 1. Project - Custom Object Detection ├── Object_Detection.py └── Train_YoloV3_Multiple.ipynb /README.md: -------------------------------------------------------------------------------- 1 | # Youtube 2 | Python: Real-time Single & Multiple Custom Object Detection with Colab (GPU), Yolov3 and OpenCV 3 | 1) Please access the folder - 1. Project - Custom Object Detection 4 | 2) Download Train_YoloV3_Multiple.ipynb for training custom objects 5 | -------------------------------------------------------------------------------- /1. Project - Custom Object Detection/Object_Detection.py: -------------------------------------------------------------------------------- 1 | import cv2 2 | import numpy as np 3 | 4 | net = cv2.dnn.readNet('yolov3_training_last.weights', 'yolov3_testing.cfg') 5 | 6 | classes = [] 7 | with open("classes.txt", "r") as f: 8 | classes = f.read().splitlines() 9 | 10 | cap = cv2.VideoCapture('test1.mp4') 11 | font = cv2.FONT_HERSHEY_PLAIN 12 | colors = np.random.uniform(0, 255, size=(100, 3)) 13 | 14 | while True: 15 | _, img = cap.read() 16 | height, width, _ = img.shape 17 | 18 | blob = cv2.dnn.blobFromImage(img, 1/255, (416, 416), (0,0,0), swapRB=True, crop=False) 19 | net.setInput(blob) 20 | output_layers_names = net.getUnconnectedOutLayersNames() 21 | layerOutputs = net.forward(output_layers_names) 22 | 23 | boxes = [] 24 | confidences = [] 25 | class_ids = [] 26 | 27 | for output in layerOutputs: 28 | for detection in output: 29 | scores = detection[5:] 30 | class_id = np.argmax(scores) 31 | confidence = scores[class_id] 32 | if confidence > 0.2: 33 | center_x = int(detection[0]*width) 34 | center_y = int(detection[1]*height) 35 | w = int(detection[2]*width) 36 | h = int(detection[3]*height) 37 | 38 | x = int(center_x - w/2) 39 | y = int(center_y - h/2) 40 | 41 | boxes.append([x, y, w, h]) 42 | confidences.append((float(confidence))) 43 | class_ids.append(class_id) 44 | 45 | indexes = cv2.dnn.NMSBoxes(boxes, confidences, 0.2, 0.4) 46 | 47 | if len(indexes)>0: 48 | for i in indexes.flatten(): 49 | x, y, w, h = boxes[i] 50 | label = str(classes[class_ids[i]]) 51 | confidence = str(round(confidences[i],2)) 52 | color = colors[i] 53 | cv2.rectangle(img, (x,y), (x+w, y+h), color, 2) 54 | cv2.putText(img, label + " " + confidence, (x, y+20), font, 2, (255,255,255), 2) 55 | 56 | cv2.imshow('Image', img) 57 | key = cv2.waitKey(1) 58 | if key==27: 59 | break 60 | 61 | cap.release() 62 | cv2.destroyAllWindows() -------------------------------------------------------------------------------- /1. Project - Custom Object Detection/Train_YoloV3_Multiple.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "nbformat": 4, 3 | "nbformat_minor": 0, 4 | "metadata": { 5 | "colab": { 6 | "name": "Train_YoloV3_Multiple.ipynb", 7 | "provenance": [], 8 | "collapsed_sections": [] 9 | }, 10 | "kernelspec": { 11 | "name": "python3", 12 | "display_name": "Python 3" 13 | }, 14 | "accelerator": "GPU" 15 | }, 16 | "cells": [ 17 | { 18 | "cell_type": "markdown", 19 | "metadata": { 20 | "id": "wHBQcQzjD6HJ", 21 | "colab_type": "text" 22 | }, 23 | "source": [ 24 | "**Connect google drive**" 25 | ] 26 | }, 27 | { 28 | "cell_type": "code", 29 | "metadata": { 30 | "id": "bwp6NIrsZZFP", 31 | "colab_type": "code", 32 | "colab": {} 33 | }, 34 | "source": [ 35 | "# Check if NVIDIA GPU is enabled\n", 36 | "!nvidia-smi" 37 | ], 38 | "execution_count": 0, 39 | "outputs": [] 40 | }, 41 | { 42 | "cell_type": "code", 43 | "metadata": { 44 | "id": "9e9ZW3sqMEPO", 45 | "colab_type": "code", 46 | "colab": {} 47 | }, 48 | "source": [ 49 | "from google.colab import drive\n", 50 | "drive.mount('/content/gdrive')\n", 51 | "!ln -s /content/gdrive/My\\ Drive/ /mydrive\n", 52 | "!ls /mydrive" 53 | ], 54 | "execution_count": 0, 55 | "outputs": [] 56 | }, 57 | { 58 | "cell_type": "markdown", 59 | "metadata": { 60 | "id": "t7utW4in4azV", 61 | "colab_type": "text" 62 | }, 63 | "source": [ 64 | "**1) Clone, configure & compile Darknet**\n", 65 | "\n" 66 | ] 67 | }, 68 | { 69 | "cell_type": "code", 70 | "metadata": { 71 | "id": "e03U7Zi-qMr2", 72 | "colab_type": "code", 73 | "colab": {} 74 | }, 75 | "source": [ 76 | "# Clone\n", 77 | "!git clone https://github.com/AlexeyAB/darknet" 78 | ], 79 | "execution_count": 0, 80 | "outputs": [] 81 | }, 82 | { 83 | "cell_type": "code", 84 | "metadata": { 85 | "id": "7hzfEWSuONhz", 86 | "colab_type": "code", 87 | "colab": {} 88 | }, 89 | "source": [ 90 | "# Configure\n", 91 | "%cd darknet\n", 92 | "!sed -i 's/OPENCV=0/OPENCV=1/' Makefile\n", 93 | "!sed -i 's/GPU=0/GPU=1/' Makefile\n", 94 | "!sed -i 's/CUDNN=0/CUDNN=1/' Makefile" 95 | ], 96 | "execution_count": 0, 97 | "outputs": [] 98 | }, 99 | { 100 | "cell_type": "code", 101 | "metadata": { 102 | "id": "EBBokOq5OOA5", 103 | "colab_type": "code", 104 | "colab": {} 105 | }, 106 | "source": [ 107 | "# Compile\n", 108 | "!make" 109 | ], 110 | "execution_count": 0, 111 | "outputs": [] 112 | }, 113 | { 114 | "cell_type": "markdown", 115 | "metadata": { 116 | "id": "gAOLtA_qI9vF", 117 | "colab_type": "text" 118 | }, 119 | "source": [ 120 | "**2) Configure yolov3.cfg file**" 121 | ] 122 | }, 123 | { 124 | "cell_type": "code", 125 | "metadata": { 126 | "id": "s-RpscgU853t", 127 | "colab_type": "code", 128 | "colab": {} 129 | }, 130 | "source": [ 131 | "# Make a copy of yolov3.cfg\n", 132 | "!cp cfg/yolov3.cfg cfg/yolov3_training.cfg" 133 | ], 134 | "execution_count": 0, 135 | "outputs": [] 136 | }, 137 | { 138 | "cell_type": "code", 139 | "metadata": { 140 | "id": "5ZgVQRop_vwR", 141 | "colab_type": "code", 142 | "colab": {} 143 | }, 144 | "source": [ 145 | "# Change lines in yolov3.cfg file\n", 146 | "!sed -i 's/batch=1/batch=64/' cfg/yolov3_training.cfg\n", 147 | "!sed -i 's/subdivisions=1/subdivisions=16/' cfg/yolov3_training.cfg\n", 148 | "!sed -i 's/max_batches = 500200/max_batches = 6000/' cfg/yolov3_training.cfg\n", 149 | "!sed -i '610 s@classes=80@classes=3@' cfg/yolov3_training.cfg\n", 150 | "!sed -i '696 s@classes=80@classes=3@' cfg/yolov3_training.cfg\n", 151 | "!sed -i '783 s@classes=80@classes=3@' cfg/yolov3_training.cfg\n", 152 | "!sed -i '603 s@filters=255@filters=24@' cfg/yolov3_training.cfg\n", 153 | "!sed -i '689 s@filters=255@filters=24@' cfg/yolov3_training.cfg\n", 154 | "!sed -i '776 s@filters=255@filters=24@' cfg/yolov3_training.cfg" 155 | ], 156 | "execution_count": 0, 157 | "outputs": [] 158 | }, 159 | { 160 | "cell_type": "markdown", 161 | "metadata": { 162 | "id": "88p9BIjkPTRv", 163 | "colab_type": "text" 164 | }, 165 | "source": [ 166 | "**3) Create .names and .data files**" 167 | ] 168 | }, 169 | { 170 | "cell_type": "code", 171 | "metadata": { 172 | "id": "7AIBw_psIclz", 173 | "colab_type": "code", 174 | "colab": {} 175 | }, 176 | "source": [ 177 | "!echo -e 'Wearing Mask\\n2nd item\\n3rd item' > data/obj.names\n", 178 | "!echo -e 'classes= 3\\ntrain = data/train.txt\\nvalid = data/test.txt\\nnames = data/obj.names\\nbackup = /mydrive/yolov3' > data/obj.data" 179 | ], 180 | "execution_count": 0, 181 | "outputs": [] 182 | }, 183 | { 184 | "cell_type": "markdown", 185 | "metadata": { 186 | "id": "dqFFqbUJMtN-", 187 | "colab_type": "text" 188 | }, 189 | "source": [ 190 | "**4) Save yolov3_training.cfg and obj.names files in Google drive**" 191 | ] 192 | }, 193 | { 194 | "cell_type": "code", 195 | "metadata": { 196 | "id": "67o96gV7L0Uv", 197 | "colab_type": "code", 198 | "colab": {} 199 | }, 200 | "source": [ 201 | "!cp cfg/yolov3_training.cfg /mydrive/yolov3/yolov3_testing.cfg\n", 202 | "!cp data/obj.names /mydrive/yolov3/classes.txt" 203 | ], 204 | "execution_count": 0, 205 | "outputs": [] 206 | }, 207 | { 208 | "cell_type": "markdown", 209 | "metadata": { 210 | "id": "9RbVKJjoncW2", 211 | "colab_type": "text" 212 | }, 213 | "source": [ 214 | "**5) Create a folder and unzip image dataset**" 215 | ] 216 | }, 217 | { 218 | "cell_type": "code", 219 | "metadata": { 220 | "id": "eZlkzFMW7I_N", 221 | "colab_type": "code", 222 | "colab": {} 223 | }, 224 | "source": [ 225 | "!mkdir data/obj\n", 226 | "!unzip /mydrive/yolov3/images.zip -d data/obj" 227 | ], 228 | "execution_count": 0, 229 | "outputs": [] 230 | }, 231 | { 232 | "cell_type": "markdown", 233 | "metadata": { 234 | "id": "ogBdNwRaZ50U", 235 | "colab_type": "text" 236 | }, 237 | "source": [ 238 | "**6) Create train.txt file**" 239 | ] 240 | }, 241 | { 242 | "cell_type": "code", 243 | "metadata": { 244 | "id": "DGUyXxeYX0IP", 245 | "colab_type": "code", 246 | "colab": {} 247 | }, 248 | "source": [ 249 | "import glob\n", 250 | "images_list = glob.glob(\"data/obj/*.jpg\")\n", 251 | "with open(\"data/train.txt\", \"w\") as f:\n", 252 | " f.write(\"\\n\".join(images_list))" 253 | ], 254 | "execution_count": 0, 255 | "outputs": [] 256 | }, 257 | { 258 | "cell_type": "markdown", 259 | "metadata": { 260 | "id": "084L-LLPqxQe", 261 | "colab_type": "text" 262 | }, 263 | "source": [ 264 | "**7) Download pre-trained weights for the convolutional layers file**" 265 | ] 266 | }, 267 | { 268 | "cell_type": "code", 269 | "metadata": { 270 | "id": "jhb5nZvsQ_96", 271 | "colab_type": "code", 272 | "colab": {} 273 | }, 274 | "source": [ 275 | "!wget https://pjreddie.com/media/files/darknet53.conv.74" 276 | ], 277 | "execution_count": 0, 278 | "outputs": [] 279 | }, 280 | { 281 | "cell_type": "markdown", 282 | "metadata": { 283 | "id": "CeSiuLrXoAjc", 284 | "colab_type": "text" 285 | }, 286 | "source": [ 287 | "**8) Start training**" 288 | ] 289 | }, 290 | { 291 | "cell_type": "code", 292 | "metadata": { 293 | "id": "S3_g3jclUzMm", 294 | "colab_type": "code", 295 | "colab": {} 296 | }, 297 | "source": [ 298 | "!./darknet detector train data/obj.data cfg/yolov3_training.cfg darknet53.conv.74 -dont_show\n", 299 | "# Uncomment below and comment above to re-start your training from last saved weights\n", 300 | "#!./darknet detector train data/obj.data cfg/yolov3_training.cfg /mydrive/yolov3/yolov3_training_last.weights -dont_show" 301 | ], 302 | "execution_count": 0, 303 | "outputs": [] 304 | } 305 | ] 306 | } --------------------------------------------------------------------------------