|
2 | 2 | "cells": [ |
3 | 3 | { |
4 | 4 | "cell_type": "code", |
5 | | - "execution_count": 1, |
| 5 | + "execution_count": 3, |
6 | 6 | "metadata": {}, |
7 | 7 | "outputs": [], |
8 | 8 | "source": [ |
|
13 | 13 | ] |
14 | 14 | }, |
15 | 15 | { |
16 | | - "cell_type": "code", |
17 | | - "execution_count": 2, |
| 16 | + "cell_type": "markdown", |
18 | 17 | "metadata": {}, |
19 | | - "outputs": [], |
20 | 18 | "source": [ |
21 | | - "maxLost = 60 # maximum number of lost" |
| 19 | + "##### Object Tracking Class" |
22 | 20 | ] |
23 | 21 | }, |
24 | 22 | { |
25 | 23 | "cell_type": "code", |
26 | | - "execution_count": 3, |
| 24 | + "execution_count": 4, |
27 | 25 | "metadata": {}, |
28 | 26 | "outputs": [], |
29 | 27 | "source": [ |
30 | 28 | "class Tracker:\n", |
31 | | - " def __init__(self, maxLost = maxLost):\n", |
| 29 | + " def __init__(self, maxLost = 30): # maxLost: maximum object lost counted when the object is being tracked\n", |
32 | 30 | " self.nextObjectID = 0 # ID of next object\n", |
33 | 31 | " self.objects = OrderedDict() # stores ID:Locations\n", |
34 | 32 | " self.lost = OrderedDict() # stores ID:Lost_count\n", |
|
41 | 39 | " \n", |
42 | 40 | " self.nextObjectID += 1\n", |
43 | 41 | " \n", |
44 | | - " def removeObject(self, objectID):\n", |
45 | | - " # remove tracker data after object is lost\n", |
| 42 | + " def removeObject(self, objectID): # remove tracker data after object is lost\n", |
46 | 43 | " del self.objects[objectID]\n", |
47 | 44 | " del self.lost[objectID]\n", |
48 | 45 | " \n", |
|
109 | 106 | " return self.objects\n" |
110 | 107 | ] |
111 | 108 | }, |
| 109 | + { |
| 110 | + "cell_type": "markdown", |
| 111 | + "metadata": {}, |
| 112 | + "source": [ |
| 113 | + "##### Loading Object Detector Model\n", |
| 114 | + "\n", |
| 115 | + "Here, the Face Detection Caffe Model is used.\n", |
| 116 | + "\n", |
| 117 | + "The files are taken from the following link:\n", |
| 118 | + "https://github.com/opencv/opencv_3rdparty/tree/dnn_samples_face_detector_20170830\n" |
| 119 | + ] |
| 120 | + }, |
112 | 121 | { |
113 | 122 | "cell_type": "code", |
114 | | - "execution_count": 4, |
| 123 | + "execution_count": 5, |
115 | 124 | "metadata": {}, |
116 | 125 | "outputs": [], |
117 | 126 | "source": [ |
118 | | - "tracker = Tracker()\n", |
119 | | - "caffemodel = {\"prototxt\":\"./deploy.prototxt\", \"model\":\"./res10_300x300_ssd_iter_140000.caffemodel\", \"acc_threshold\":0.50}\n", |
| 127 | + "caffemodel = {\"prototxt\":\"./deploy.prototxt\",\n", |
| 128 | + " \"model\":\"./res10_300x300_ssd_iter_140000.caffemodel\",\n", |
| 129 | + " \"acc_threshold\":0.50 # neglected detections with probability less than acc_threshold value\n", |
| 130 | + " }\n", |
| 131 | + "\n", |
120 | 132 | "net = cv.dnn.readNetFromCaffe(caffemodel[\"prototxt\"], caffemodel[\"model\"])" |
121 | 133 | ] |
122 | 134 | }, |
| 135 | + { |
| 136 | + "cell_type": "markdown", |
| 137 | + "metadata": {}, |
| 138 | + "source": [ |
| 139 | + "##### Instantiate the Tracker Class" |
| 140 | + ] |
| 141 | + }, |
123 | 142 | { |
124 | 143 | "cell_type": "code", |
125 | | - "execution_count": null, |
| 144 | + "execution_count": 6, |
| 145 | + "metadata": {}, |
| 146 | + "outputs": [], |
| 147 | + "source": [ |
| 148 | + "maxLost = 60 # maximum number of object losts counted when the object is being tracked\n", |
| 149 | + "tracker = Tracker(maxLost = maxLost)" |
| 150 | + ] |
| 151 | + }, |
| 152 | + { |
| 153 | + "cell_type": "markdown", |
| 154 | + "metadata": {}, |
| 155 | + "source": [ |
| 156 | + "##### Initiate opencv video capture object\n", |
| 157 | + "\n", |
| 158 | + "The `video_src` can take two values:\n", |
| 159 | + "1. If `video_src=0`: OpenCV accesses the camera connected through USB\n", |
| 160 | + "2. If `video_src='video_file_path'`: OpenCV will access the video file at the given path (can be MP4, AVI, etc format)" |
| 161 | + ] |
| 162 | + }, |
| 163 | + { |
| 164 | + "cell_type": "code", |
| 165 | + "execution_count": 7, |
| 166 | + "metadata": {}, |
| 167 | + "outputs": [], |
| 168 | + "source": [ |
| 169 | + "video_src = 0\n", |
| 170 | + "cap = cv.VideoCapture(video_src) " |
| 171 | + ] |
| 172 | + }, |
| 173 | + { |
| 174 | + "cell_type": "markdown", |
| 175 | + "metadata": {}, |
| 176 | + "source": [ |
| 177 | + "##### Start object detection and tracking" |
| 178 | + ] |
| 179 | + }, |
| 180 | + { |
| 181 | + "cell_type": "code", |
| 182 | + "execution_count": 8, |
126 | 183 | "metadata": { |
127 | 184 | "scrolled": true |
128 | 185 | }, |
129 | 186 | "outputs": [], |
130 | 187 | "source": [ |
131 | | - "cap = cv.VideoCapture(0)\n", |
132 | | - "\n", |
133 | | - "(H, W) = (None, None)\n", |
| 188 | + "(H, W) = (None, None) # input image height and width for the network\n", |
134 | 189 | "\n", |
135 | 190 | "while(True):\n", |
136 | 191 | " \n", |
|
147 | 202 | " blob = cv.dnn.blobFromImage(image, 1.0, (W, H), (104.0, 177.0, 123.0))\n", |
148 | 203 | " \n", |
149 | 204 | " net.setInput(blob)\n", |
150 | | - " detections = net.forward()\n", |
| 205 | + " detections = net.forward() # detect objects using object detection model\n", |
151 | 206 | " \n", |
152 | | - " detections_bbox = [] # bounding box for detections\n", |
| 207 | + " detections_bbox = [] # bounding box for detections\n", |
153 | 208 | " \n", |
154 | 209 | " for i in range(0, detections.shape[2]):\n", |
155 | 210 | " if detections[0, 0, i, 2] > caffemodel[\"acc_threshold\"]:\n", |
|
160 | 215 | " (startX, startY, endX, endY) = box.astype(\"int\")\n", |
161 | 216 | " cv.rectangle(image, (startX, startY), (endX, endY), (0, 255, 0), 2) \n", |
162 | 217 | " \n", |
163 | | - " objects = tracker.update(detections_bbox)\n", |
| 218 | + " objects = tracker.update(detections_bbox) # update tracker based on the newly detected objects\n", |
164 | 219 | " \n", |
165 | 220 | " for (objectID, centroid) in objects.items():\n", |
166 | 221 | " text = \"ID {}\".format(objectID)\n", |
|
0 commit comments