Charalambos Georgiades commited on
Commit
98ab999
1 Parent(s): 97672ff

Added files

Browse files
Files changed (3) hide show
  1. detector.py +113 -0
  2. packages.txt +2 -0
  3. requirements.txt +5 -0
detector.py ADDED
@@ -0,0 +1,113 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import numpy as np
2
+ import cv2
3
+ from pathlib import Path
4
+
5
+
6
+ class Detector():
7
+ def __init__(self, weights="yolov4-tiny.weights", config_file = "tiny-yolov4.cfg",
8
+ classes_file=Path(__file__).parent / 'cfg' / 'coco.names', conf_thresh=0.25, nms_thresh=0.4,
9
+ netsize=[416, 416]):
10
+
11
+ """ Detector class that implements yolo detector
12
+ Parameters
13
+ ----------
14
+ weights : string
15
+ path to the weights file, eg. yolov4-tiny.weights
16
+ config_file : string
17
+ path to the configs file, eg. tiny-yolov4.cfg
18
+ classes_file : string
19
+ path to the classes file, eg. coco.names
20
+ conf_thresh : float
21
+ confidence threshold for the detection
22
+ nms_thresh : float
23
+ non maxima supression threshold for the detections
24
+ netsize : tuple
25
+ netwrork's config size eg. [416,416]
26
+ """
27
+ self.weights = weights
28
+ self.config = config_file
29
+ self.classes_file = classes_file
30
+ # initialize the network
31
+ self.net = cv2.dnn.readNet(self.weights, self.config)
32
+ # self.net = cv2.dnn.readNetFromDarknet(self.config, self.weights)
33
+ # set the backend
34
+ self.net.setPreferableBackend(cv2.dnn.DNN_BACKEND_CUDA)
35
+ self.net.setPreferableTarget(cv2.dnn.DNN_TARGET_CUDA)
36
+
37
+ ln = self.net.getLayerNames()
38
+ # an error checking due to OPENCV versions changes
39
+ try:
40
+ self.vers = 0
41
+ self.layers = [ln[i[0] - 1] for i in self.net.getUnconnectedOutLayers()]
42
+ except:
43
+ self.vers = 1
44
+ self.layers = [ln[i - 1] for i in self.net.getUnconnectedOutLayers()]
45
+
46
+ self.netsize = netsize
47
+ self.conf_thresh = conf_thresh
48
+ self.nms_thresh = nms_thresh
49
+ with open(self.classes_file, 'r') as f:
50
+ classes = [line.strip() for line in f.readlines()]
51
+ self.labels = np.array(classes, dtype=str)
52
+ self.model = cv2.dnn_DetectionModel(self.net)
53
+ self.model.setInputParams(size=(self.netsize[0], self.netsize[1]), scale=1 / 256)
54
+ self.COLORS = np.random.randint(0, 255, size=(len(self.labels), 3))
55
+
56
+ def detect(self, img_or):
57
+
58
+ # copy the original image
59
+ img = img_or.copy()
60
+ # do some pre-processing (eg. resizing)
61
+ image = self._preprocess(img)
62
+ try:
63
+ # detect the image
64
+ classes, scores, boxes = self.model.detect(image, self.conf_thresh,
65
+ self.nms_thresh)
66
+ except Exception as e:
67
+ print("[ERROR ]" + e)
68
+ if len(boxes)==0:
69
+ return img, [], [], []
70
+
71
+ # de-normalize the results
72
+ fixboxes = self.de_normalize(boxes,self.netsize, self.imgsize)
73
+ boxes = np.array(fixboxes,dtype=np.int32)
74
+ # draw the detections on the image
75
+ image_det = self.postprocess(classes, scores, boxes, img)
76
+
77
+ return image_det, classes, scores, boxes
78
+
79
+ def _preprocess(self, frame):
80
+ self.imgsize = [frame.shape[1], frame.shape[0]]
81
+ img = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
82
+ return cv2.resize(img, (self.netsize[0], self.netsize[1]), interpolation=cv2.INTER_LINEAR)
83
+
84
+ def de_normalize(self, boxes,netsize,imgsize):
85
+ finBoxes = []
86
+ for i in range(len(boxes)):
87
+ box = boxes[i]
88
+ x,y,w,h= int((box[0] / netsize[0]) * imgsize[0]),int((box[1] / netsize[1]) * imgsize[1]),\
89
+ int((box[2] / netsize[0]) * imgsize[0]), int((box[3] / netsize[1]) * imgsize[1])
90
+ finBoxes.append((x,y,w,h))
91
+ return finBoxes
92
+
93
+ # drawing bounding boxes and their label on the detections
94
+ def postprocess(self, classes, scores, boxes, img):
95
+ for i in range(len(boxes)):
96
+ box = boxes[i]
97
+ if scores[i] > self.conf_thresh:
98
+ x,y,w,h = box
99
+ if self.vers == 1:
100
+ class_id = classes[i]
101
+ score = scores[i]
102
+ color = [int(c) for c in self.COLORS[class_id]]
103
+ else:
104
+ class_id = classes[i][0]
105
+ score = scores[i][0]
106
+ color = self.COLORS[class_id]
107
+ color = (int(color[0]), int(color[1]), int(color[2]))
108
+ cv2.rectangle(img, (x, y), (x + w, y + h), color, 2)
109
+ text = "{}: {:.4f}".format(self.labels[class_id], score)
110
+ cv2.putText(img, text, (x, y - 5), cv2.FONT_HERSHEY_SIMPLEX,
111
+ 0.5, color, 2)
112
+ return img
113
+
packages.txt ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ python3-opencv
2
+ ffmpeg
requirements.txt ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ opencv-python
2
+ ffmpeg-python
3
+ numpy
4
+ pandas
5
+ matplotlib