|
| 1 | +#! /usr/bin/env python |
| 2 | +# -*- coding: utf-8 -*- |
| 3 | + |
| 4 | +from __future__ import division, print_function, absolute_import |
| 5 | +import sys |
| 6 | +#sys.path.remove('/opt/ros/kinetic/lib/python2.7/dist-packages') |
| 7 | +import os |
| 8 | +import datetime |
| 9 | +from timeit import time |
| 10 | +import warnings |
| 11 | +import cv2 |
| 12 | +import numpy as np |
| 13 | +import argparse |
| 14 | +from PIL import Image |
| 15 | +from yolo import YOLO |
| 16 | + |
| 17 | +from deep_sort import preprocessing |
| 18 | +from deep_sort import nn_matching |
| 19 | +from deep_sort.detection import Detection |
| 20 | +from deep_sort.tracker import Tracker |
| 21 | +from tools import generate_detections as gdet |
| 22 | +from deep_sort.detection import Detection as ddet |
| 23 | +from collections import deque |
| 24 | +from keras import backend |
| 25 | +import tensorflow as tf |
| 26 | +from tensorflow.compat.v1 import InteractiveSession |
| 27 | +config = tf.ConfigProto() |
| 28 | +config.gpu_options.allow_growth = True |
| 29 | +session = InteractiveSession(config=config) |
| 30 | + |
| 31 | + |
| 32 | +ap = argparse.ArgumentParser() |
| 33 | +ap.add_argument("-i", "--input",help="path to input video", default = "./test_video/TownCentreXVID.avi") |
| 34 | +ap.add_argument("-c", "--class",help="name of class", default = "person") |
| 35 | +args = vars(ap.parse_args()) |
| 36 | + |
| 37 | +pts = [deque(maxlen=30) for _ in range(9999)] |
| 38 | +warnings.filterwarnings('ignore') |
| 39 | + |
| 40 | +# initialize a list of colors to represent each possible class label |
| 41 | +np.random.seed(100) |
| 42 | +COLORS = np.random.randint(0, 255, size=(200, 3), |
| 43 | + dtype="uint8") |
| 44 | +#list = [[] for _ in range(100)] |
| 45 | + |
| 46 | +def main(yolo): |
| 47 | + |
| 48 | + start = time.time() |
| 49 | + max_cosine_distance = 0.3 |
| 50 | + nn_budget = None |
| 51 | + nms_max_overlap = 1.0 |
| 52 | + |
| 53 | + counter = [] |
| 54 | + #deep_sort |
| 55 | + model_filename = 'model_data/market1501.pb' |
| 56 | + encoder = gdet.create_box_encoder(model_filename,batch_size=1) |
| 57 | + |
| 58 | + find_objects = ['person'] |
| 59 | + metric = nn_matching.NearestNeighborDistanceMetric("cosine", max_cosine_distance, nn_budget) |
| 60 | + tracker = Tracker(metric) |
| 61 | + |
| 62 | + writeVideo_flag = True |
| 63 | + video_capture = cv2.VideoCapture(args["input"]) |
| 64 | + |
| 65 | + |
| 66 | + if writeVideo_flag: |
| 67 | + # Define the codec and create VideoWriter object |
| 68 | + w = int(video_capture.get(3)) |
| 69 | + h = int(video_capture.get(4)) |
| 70 | + fourcc = cv2.VideoWriter_fourcc(*'MJPG') |
| 71 | + out = cv2.VideoWriter('./output/output.avi', fourcc, 15, (w, h)) |
| 72 | + list_file = open('detection_rslt.txt', 'w') |
| 73 | + frame_index = -1 |
| 74 | + |
| 75 | + fps = 0.0 |
| 76 | + |
| 77 | + while True: |
| 78 | + |
| 79 | + ret, frame = video_capture.read() # frame shape 640*480*3 |
| 80 | + if ret != True: |
| 81 | + break |
| 82 | + t1 = time.time() |
| 83 | + |
| 84 | + #image = Image.fromarray(frame) |
| 85 | + image = Image.fromarray(frame[...,::-1]) #bgr to rgb |
| 86 | + boxs, confidence, class_names = yolo.detect_image(image) |
| 87 | + features = encoder(frame,boxs) |
| 88 | + # score to 1.0 here). |
| 89 | + detections = [Detection(bbox, 1.0, feature) for bbox, feature in zip(boxs, features)] |
| 90 | + # Run non-maxima suppression. |
| 91 | + boxes = np.array([d.tlwh for d in detections]) |
| 92 | + scores = np.array([d.confidence for d in detections]) |
| 93 | + indices = preprocessing.non_max_suppression(boxes, nms_max_overlap, scores) |
| 94 | + detections = [detections[i] for i in indices] |
| 95 | + |
| 96 | + # Call the tracker |
| 97 | + tracker.predict() |
| 98 | + tracker.update(detections) |
| 99 | + |
| 100 | + i = int(0) |
| 101 | + indexIDs = [] |
| 102 | + c = [] |
| 103 | + boxes = [] |
| 104 | + |
| 105 | + for det in detections: |
| 106 | + bbox = det.to_tlbr() |
| 107 | + cv2.rectangle(frame,(int(bbox[0]), int(bbox[1])), (int(bbox[2]), int(bbox[3])),(255,255,255), 2) |
| 108 | + #print(class_names) |
| 109 | + #print(class_names[p]) |
| 110 | + |
| 111 | + for track in tracker.tracks: |
| 112 | + if not track.is_confirmed() or track.time_since_update > 1: |
| 113 | + continue |
| 114 | + #boxes.append([track[0], track[1], track[2], track[3]]) |
| 115 | + indexIDs.append(int(track.track_id)) |
| 116 | + counter.append(int(track.track_id)) |
| 117 | + bbox = track.to_tlbr() |
| 118 | + color = [int(c) for c in COLORS[indexIDs[i] % len(COLORS)]] |
| 119 | + #print(frame_index) |
| 120 | + list_file.write(str(frame_index)+',') |
| 121 | + list_file.write(str(track.track_id)+',') |
| 122 | + cv2.rectangle(frame, (int(bbox[0]), int(bbox[1])), (int(bbox[2]), int(bbox[3])),(color), 3) |
| 123 | + b0 = str(bbox[0])#.split('.')[0] + '.' + str(bbox[0]).split('.')[0][:1] |
| 124 | + b1 = str(bbox[1])#.split('.')[0] + '.' + str(bbox[1]).split('.')[0][:1] |
| 125 | + b2 = str(bbox[2]-bbox[0])#.split('.')[0] + '.' + str(bbox[3]).split('.')[0][:1] |
| 126 | + b3 = str(bbox[3]-bbox[1]) |
| 127 | + |
| 128 | + list_file.write(str(b0) + ','+str(b1) + ','+str(b2) + ','+str(b3)) |
| 129 | + #print(str(track.track_id)) |
| 130 | + list_file.write('\n') |
| 131 | + #list_file.write(str(track.track_id)+',') |
| 132 | + cv2.putText(frame,str(track.track_id),(int(bbox[0]), int(bbox[1] -50)),0, 5e-3 * 150, (color),2) |
| 133 | + if len(class_names) > 0: |
| 134 | + class_name = class_names[0] |
| 135 | + cv2.putText(frame, str(class_names[0]),(int(bbox[0]), int(bbox[1] -20)),0, 5e-3 * 150, (color),2) |
| 136 | + |
| 137 | + i += 1 |
| 138 | + #bbox_center_point(x,y) |
| 139 | + center = (int(((bbox[0])+(bbox[2]))/2),int(((bbox[1])+(bbox[3]))/2)) |
| 140 | + #track_id[center] |
| 141 | + |
| 142 | + pts[track.track_id].append(center) |
| 143 | + |
| 144 | + thickness = 5 |
| 145 | + #center point |
| 146 | + cv2.circle(frame, (center), 1, color, thickness) |
| 147 | + |
| 148 | + # draw motion path |
| 149 | + for j in range(1, len(pts[track.track_id])): |
| 150 | + if pts[track.track_id][j - 1] is None or pts[track.track_id][j] is None: |
| 151 | + continue |
| 152 | + thickness = int(np.sqrt(64 / float(j + 1)) * 2) |
| 153 | + cv2.line(frame,(pts[track.track_id][j-1]), (pts[track.track_id][j]),(color),thickness) |
| 154 | + #cv2.putText(frame, str(class_names[j]),(int(bbox[0]), int(bbox[1] -20)),0, 5e-3 * 150, (255,255,255),2) |
| 155 | + |
| 156 | + count = len(set(counter)) |
| 157 | + cv2.putText(frame, "Total Pedestrian Counter: "+str(count),(int(20), int(120)),0, 5e-3 * 200, (0,255,0),2) |
| 158 | + cv2.putText(frame, "Current Pedestrian Counter: "+str(i),(int(20), int(80)),0, 5e-3 * 200, (0,255,0),2) |
| 159 | + cv2.putText(frame, "FPS: %f"%(fps),(int(20), int(40)),0, 5e-3 * 200, (0,255,0),3) |
| 160 | + cv2.namedWindow("YOLO4_Deep_SORT", 0); |
| 161 | + cv2.resizeWindow('YOLO4_Deep_SORT', 1024, 768); |
| 162 | + cv2.imshow('YOLO4_Deep_SORT', frame) |
| 163 | + |
| 164 | + |
| 165 | + if writeVideo_flag: |
| 166 | + # save a frame |
| 167 | + out.write(frame) |
| 168 | + frame_index = frame_index + 1 |
| 169 | + |
| 170 | + |
| 171 | + fps = ( fps + (1./(time.time()-t1)) ) / 2 |
| 172 | + out.write(frame) |
| 173 | + frame_index = frame_index + 1 |
| 174 | + |
| 175 | + # Press Q to stop! |
| 176 | + if cv2.waitKey(1) & 0xFF == ord('q'): |
| 177 | + break |
| 178 | + print(" ") |
| 179 | + print("[Finish]") |
| 180 | + end = time.time() |
| 181 | + |
| 182 | + if len(pts[track.track_id]) != None: |
| 183 | + print(args["input"][43:57]+": "+ str(count) + " " + str(class_name) +' Found') |
| 184 | + |
| 185 | + else: |
| 186 | + print("[No Found]") |
| 187 | + #print("[INFO]: model_image_size = (960, 960)") |
| 188 | + video_capture.release() |
| 189 | + if writeVideo_flag: |
| 190 | + out.release() |
| 191 | + list_file.close() |
| 192 | + cv2.destroyAllWindows() |
| 193 | + |
| 194 | +if __name__ == '__main__': |
| 195 | + main(YOLO()) |
0 commit comments