-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathyoloModule.py
More file actions
147 lines (110 loc) · 5.78 KB
/
yoloModule.py
File metadata and controls
147 lines (110 loc) · 5.78 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
################################################################################
# Example : performs YOLO (v3) object detection from a video file
# specified on the command line (e.g. python FILE.py video_file) or from an
# attached web camera
# Author : Toby Breckon, toby.breckon@durham.ac.uk
# Modified by: jbrp94, jbrp94@durham.ac.uk
# Changed into a callable module
# Copyright (c) 2019 Toby Breckon, Durham University, UK
# License : LGPL - http://www.gnu.org/licenses/lgpl.html
# Implements the You Only Look Once (YOLO) object detection architecture decribed in full in:
# Redmon, J., & Farhadi, A. (2018). Yolov3: An incremental improvement. arXiv preprint arXiv:1804.02767.
# https://pjreddie.com/media/files/papers/YOLOv3.pdf
# This code: significant portions based in part on the tutorial and example available at:
# https://www.learnopencv.com/deep-learning-based-object-detection-using-yolov3-with-opencv-python-c/
# https://github.com/spmallick/learnopencv/blob/master/ObjectDetection-YOLO/object_detection_yolo.py
# under LICENSE: https://github.com/spmallick/learnopencv/blob/master/ObjectDetection-YOLO/LICENSE
# To use first download the following files:
# https://pjreddie.com/media/files/yolov3.weights
# https://github.com/pjreddie/darknet/blob/master/cfg/yolov3.cfg?raw=true
# https://github.com/pjreddie/darknet/blob/master/data/coco.names?raw=true
################################################################################
import cv2
import argparse
import sys
import math
import numpy as np
#####################################################################
# Remove the bounding boxes with low confidence using non-maxima suppression
# image: image detection performed on
# results: output from YOLO CNN network
# threshold_confidence: threshold on keeping detection
# threshold_nms: threshold used in non maximum suppression
def postprocess(image, results, threshold_confidence, threshold_nms):
frameHeight = image.shape[0]
frameWidth = image.shape[1]
# Scan through all the bounding boxes output from the network and..
# 1. keep only the ones with high confidence scores.
# 2. assign the box class label as the class with the highest score.
# 3. construct a list of bounding boxes, class labels and confidence scores
classIds = []
confidences = []
boxes = []
for result in results:
for detection in result:
scores = detection[5:]
classId = np.argmax(scores)
confidence = scores[classId]
if confidence > threshold_confidence:
center_x = int(detection[0] * frameWidth)
center_y = int(detection[1] * frameHeight)
width = int(detection[2] * frameWidth)
height = int(detection[3] * frameHeight)
left = int(center_x - width / 2)
top = int(center_y - height / 2)
classIds.append(classId)
confidences.append(float(confidence))
boxes.append([left, top, width, height])
# Perform non maximum suppression to eliminate redundant overlapping boxes with
# lower confidences
classIds_nms = []
confidences_nms = []
boxes_nms = []
indices = cv2.dnn.NMSBoxes(boxes, confidences, threshold_confidence, threshold_nms)
for i in indices:
i = i[0]
classIds_nms.append(classIds[i])
confidences_nms.append(confidences[i])
boxes_nms.append(boxes[i])
# return post processed lists of classIds, confidences and bounding boxes
return (classIds_nms, confidences_nms, boxes_nms)
################################################################################
# Get the names of the output layers of the CNN network
# net : an OpenCV DNN module network object
def getOutputsNames(net):
# Get the names of all the layers in the network
layersNames = net.getLayerNames()
# Get the names of the output layers, i.e. the layers with unconnected outputs
return [layersNames[i[0] - 1] for i in net.getUnconnectedOutLayers()]
# init YOLO CNN object detection model
confThreshold = 0.5 # Confidence threshold
nmsThreshold = 0.4 # Non-maximum suppression threshold
inpWidth = 416 # Width of network's input image
inpHeight = 416 # Height of network's input image
# Load names of classes from file
classes = open("coco.names","r").read().rstrip('\n').split('\n')
# load configuration and weight files for the model and load the network using them
net = cv2.dnn.readNetFromDarknet("yolov3.cfg", "yolov3.weights")
output_layer_names = getOutputsNames(net)
# defaults DNN_BACKEND_INFERENCE_ENGINE if Intel Inference Engine lib available or DNN_BACKEND_OPENCV otherwise
net.setPreferableBackend(cv2.dnn.DNN_BACKEND_DEFAULT)
# change to cv2.dnn.DNN_TARGET_CPU (slower) if this causes issues (should fail gracefully if OpenCL not available)
net.setPreferableTarget(cv2.dnn.DNN_TARGET_OPENCL)
def detection(frame):
# if command line arguments are provided try to read video_name
# otherwise default to capture from attached camera
# create a 4D tensor (OpenCV 'blob') from image frame (pixels scaled 0->1, image resized)
tensor = cv2.dnn.blobFromImage(frame, 1/255, (inpWidth, inpHeight), [0,0,0], 1, crop=False)
# set the input to the CNN network
net.setInput(tensor)
# runs forward inference to get output of the final output layers
results = net.forward(output_layer_names)
# remove the bounding boxes with low confidence
classIDs, confidences, boxes = postprocess(frame, results, confThreshold, nmsThreshold)
# draw resulting detections on image
output = []
for detected_object in range(0, len(boxes)):
box = boxes[detected_object]
output.append((classes[classIDs[detected_object]],box))
return output
################################################################################