-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 8fd886b
Showing
64 changed files
with
4,272 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,271 @@ | ||
''' | ||
DeepSort Yolo algorithm in sklearn/tensorflow keras. | ||
Usage: 1) install requirements (conda recommended). | ||
2) for terminal execution: python detect.py | ||
3) from spyder, open detect.py and run file. | ||
The yolo model is created using the Functional API from tensorflow keras. | ||
''' | ||
|
||
|
||
''' | ||
Que falta: | ||
3) determinar el tamaño del hypercolumn | ||
''' | ||
import time | ||
from absl import app, logging | ||
import cv2 | ||
import numpy as np | ||
import tensorflow as tf | ||
from yolov3_tf2.models import ( | ||
YoloV3, YoloV3Tiny | ||
) | ||
from yolov3_tf2.dataset import transform_images | ||
from yolov3_tf2.utils import draw_YOLO, draw_DS, draw_output | ||
import imutils | ||
from deepsort import deepsort_rbc | ||
import warnings | ||
warnings.filterwarnings('ignore') | ||
|
||
|
||
# The following functions can be used to convert a value to a type compatible | ||
# with tf.Example. | ||
|
||
def _bytes_feature(value): | ||
"""Returns a bytes_list from a string / byte.""" | ||
if isinstance(value, type(tf.constant(0))): | ||
value = value.numpy() # BytesList won't unpack a string from an EagerTensor. | ||
return tf.train.Feature(bytes_list=tf.train.BytesList(value=[value])) | ||
|
||
def _float_feature(value): | ||
"""Returns a float_list from a float / double.""" | ||
return tf.train.Feature(float_list=tf.train.FloatList(value=[value])) | ||
|
||
def _int64_feature(value): | ||
"""Returns an int64_list from a bool / enum / int / uint.""" | ||
return tf.train.Feature(int64_list=tf.train.Int64List(value=[value])) | ||
|
||
# tf.example definition with relevant features. | ||
def frame_example(raw, frame): | ||
|
||
feature = { | ||
'frame': _int64_feature(frame), | ||
'raw_features': _bytes_feature(tf.io.serialize_tensor(raw)), | ||
} | ||
|
||
return tf.train.Example(features=tf.train.Features(feature=feature)) | ||
|
||
|
||
# Data object with settings | ||
FLAGS = type('', (), {})() | ||
FLAGS.classes = './data/coco.names' | ||
# change weights file if using tiny_yolo (weights trained using COCO DB) | ||
FLAGS.weights = './checkpoints/yolov3.tf' | ||
# set to "True" if using tiny_yolo | ||
FLAGS.tiny = False | ||
FLAGS.size = 416 | ||
FLAGS.num_classes = 80 | ||
FLAGS.save = None # flag for saving features | ||
|
||
# for video | ||
FLAGS.video = './input/vdo.avi' | ||
FLAGS.output = [] | ||
FLAGS.output_format = 'XVID' | ||
|
||
# Main code | ||
def main(_argv): | ||
# try access to GPU | ||
physical_devices = tf.config.experimental.list_physical_devices('GPU') | ||
if len(physical_devices) > 0: | ||
tf.config.experimental.set_memory_growth(physical_devices[0], True) | ||
# Create Yolo model (Tiny or complete) | ||
if FLAGS.tiny: | ||
# light version (faster processing) | ||
yolo = YoloV3Tiny(classes=FLAGS.num_classes) | ||
else: | ||
# Deeper more robust model | ||
yolo = YoloV3(classes=FLAGS.num_classes) | ||
|
||
# Load weights from a pretrained net | ||
yolo.load_weights(FLAGS.weights).expect_partial() | ||
logging.info('weights loaded') | ||
|
||
# Get classes names | ||
class_names = [c.strip() for c in open(FLAGS.classes).readlines()] | ||
logging.info('classes loaded') | ||
|
||
#Initialize deep sort. | ||
deepsort = deepsort_rbc() | ||
|
||
times = [] | ||
|
||
try: | ||
vid = cv2.VideoCapture(int(FLAGS.video)) | ||
except: | ||
vid = cv2.VideoCapture(FLAGS.video) | ||
|
||
out = None | ||
|
||
if FLAGS.output: | ||
# by default VideoCapture returns float instead of int | ||
width = int(vid.get(cv2.CAP_PROP_FRAME_WIDTH)) | ||
height = int(vid.get(cv2.CAP_PROP_FRAME_HEIGHT)) | ||
fps = int(vid.get(cv2.CAP_PROP_FPS)) | ||
codec = cv2.VideoWriter_fourcc(*"MJPG") | ||
out = cv2.VideoWriter(FLAGS.output, codec, fps, (width, height)) | ||
|
||
# try to determine the total number of frames in the video file | ||
try: | ||
prop = cv2.cv.CV_CAP_PROP_FRAME_COUNT if imutils.is_cv2() \ | ||
else cv2.CAP_PROP_FRAME_COUNT | ||
total = int(vid.get(prop)) | ||
logging.info("{} total frames in video".format(total)) | ||
# print("[INFO] {} total frames in video".format(total)) | ||
|
||
# an error occurred while trying to determine the total | ||
# number of frames in the video file | ||
except: | ||
logging.info("could not determine # of frames in video") | ||
logging.info("No approx. completion time can be provided") | ||
total = -1 | ||
|
||
# number of frames counter | ||
cont = 0 | ||
|
||
# Write Yolo features from each frame to `images.tfrecords`. | ||
record_file = 'Test.tfrecords' | ||
with tf.io.TFRecordWriter(record_file) as writer: | ||
while True: | ||
_, img = vid.read() | ||
|
||
if img is None: | ||
logging.warning("Empty Frame") | ||
time.sleep(0.1) | ||
break | ||
|
||
# print(cont) | ||
img_in = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) | ||
img_in = tf.expand_dims(img_in, 0) | ||
img_in = transform_images(img_in, FLAGS.size) | ||
|
||
t1 = time.time() | ||
|
||
# use model to predict object bboxes | ||
t1 = time.time() | ||
ind, boxes, scores, classes, nums, feat = yolo(img_in) | ||
t2 = time.time() | ||
times.append(t2-t1) | ||
times = times[-20:] | ||
|
||
# initialize our lists of detected bounding boxes, confidences, | ||
# and class IDs, respectively | ||
bboxes_p = [] | ||
confidences = [] | ||
classIDs = [] | ||
feat_track = [] | ||
scales = [] | ||
ids = [] | ||
|
||
# feature pre-location | ||
feat_all = [] | ||
conti = 0 | ||
|
||
for j, indi in enumerate(ind): | ||
if indi is not None: | ||
for i in indi: | ||
classID = int(classes[0][int(i[4])]) | ||
if class_names[classID] == "car" or class_names[classID] == "truck": | ||
sco = np.array(scores[0][int(i[4])]) | ||
box_p = np.array(boxes[0][int(i[4])]) | ||
# logging.info('\t{}, {}, {}'.format(class_names[classID], | ||
# sco,box_p)) | ||
|
||
# Feature extraction | ||
x, y = np.array(i[1:3]) | ||
feat_1 = feat[j][:, x, y, :][0] | ||
feat_track.append(feat_1) | ||
feat_all.append(np.concatenate([feat_1, | ||
tf.expand_dims(classes[0][int(i[4])], 0), # object class | ||
tf.expand_dims(i[4], 0)], axis=0)) # id object in frame | ||
|
||
# objects allocation | ||
ids.append(conti) | ||
conti += 1 | ||
scales.append(j) | ||
confidences.append(float(sco)) | ||
bboxes_p.append(box_p) | ||
classIDs.append(classID) | ||
|
||
# save output image | ||
# img2 = draw_output(img, (bboxes_p,confidences,classIDs,ids, | ||
# scales), class_names) | ||
# cv2.imshow('output', img2) | ||
# key = cv2.waitKey(0) & 0xFF | ||
# if key == ord('q'): | ||
# break | ||
if FLAGS.save: | ||
# Save features to TFRecord | ||
if feat_all: | ||
t_feat_all = tf.convert_to_tensor(feat_all) | ||
# Process the frames into `tf.Example` messages. | ||
tf_example = frame_example(t_feat_all, cont) | ||
# Write to a `.tfrecords` file. | ||
writer.write(tf_example.SerializeToString()) | ||
|
||
# ensure at least one detection exists | ||
if bboxes_p: | ||
|
||
# if cont == 46: | ||
# print(cont) | ||
# feed deepsort with detections and features | ||
tracker, detections_class = deepsort.run_deep_sort(img, np.asarray(bboxes_p), | ||
confidences, | ||
classIDs, scales, | ||
ids, feat_track) | ||
classIDs_nms = detections_class[1] | ||
scales_nms = detections_class[2] | ||
ids_nms = detections_class[3] | ||
# prelocation employed detections | ||
boxes_nms = [] | ||
sco_nms = [] | ||
for det in detections_class[0]: | ||
# Append NMS detection boxes | ||
boxes_nms.append(det.to_tlbr()) | ||
sco_nms.append(det.confidence) | ||
|
||
# prelocation of tracked boxes | ||
boxes_ds = [] | ||
id_ds = [] | ||
for track in tracker.tracks: | ||
if not track.is_confirmed() or track.time_since_update > 1: | ||
continue | ||
#Append boxes and id. | ||
boxes_ds.append(track.to_tlbr()) #Get the corrected/predicted bounding box | ||
id_ds.append(str(track.track_id)) #Get the ID for the particular track. | ||
|
||
# save output image | ||
img = draw_YOLO(img, (boxes_nms, sco_nms, classIDs_nms, ids_nms, | ||
scales_nms), class_names) | ||
if boxes_ds: | ||
img = draw_DS(img, boxes_ds, id_ds) | ||
img = cv2.putText(img, "Time: {:.2f}ms, frame:{:d}".format(sum(times)/len(times)*1000, cont), (0, 30), | ||
cv2.FONT_HERSHEY_COMPLEX_SMALL, 1, (0, 0, 255), 2) | ||
|
||
if FLAGS.output: | ||
out.write(img) | ||
cv2.imshow('output', img) | ||
key = cv2.waitKey(100) & 0xFF | ||
if key == ord('q'): | ||
break | ||
cont += 1 | ||
cv2.destroyAllWindows() | ||
|
||
# Initialize code | ||
if __name__ == '__main__': | ||
try: | ||
app.run(main) | ||
except SystemExit: | ||
pass |
Binary file not shown.
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
Pedestrian | ||
PersonOnVehicle | ||
Car | ||
Bicycle | ||
Motorbike | ||
NonMotorizedVehicle | ||
StaticPerson | ||
Distractor | ||
Occluder | ||
OccluderOnTheGround | ||
OccluderFull | ||
Reflection | ||
Crowd |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
person | ||
bicycle | ||
car | ||
motorbike | ||
aeroplane | ||
bus | ||
train | ||
truck | ||
boat | ||
traffic light | ||
fire hydrant | ||
stop sign | ||
parking meter | ||
bench | ||
bird | ||
cat | ||
dog | ||
horse | ||
sheep | ||
cow | ||
elephant | ||
bear | ||
zebra | ||
giraffe | ||
backpack | ||
umbrella | ||
handbag | ||
tie | ||
suitcase | ||
frisbee | ||
skis | ||
snowboard | ||
sports ball | ||
kite | ||
baseball bat | ||
baseball glove | ||
skateboard | ||
surfboard | ||
tennis racket | ||
bottle | ||
wine glass | ||
cup | ||
fork | ||
knife | ||
spoon | ||
bowl | ||
banana | ||
apple | ||
sandwich | ||
orange | ||
broccoli | ||
carrot | ||
hot dog | ||
pizza | ||
donut | ||
cake | ||
chair | ||
sofa | ||
pottedplant | ||
bed | ||
diningtable | ||
toilet | ||
tvmonitor | ||
laptop | ||
mouse | ||
remote | ||
keyboard | ||
cell phone | ||
microwave | ||
oven | ||
toaster | ||
sink | ||
refrigerator | ||
book | ||
clock | ||
vase | ||
scissors | ||
teddy bear | ||
hair drier | ||
toothbrush |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
# vim: expandtab:ts=4:sw=4 |
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Oops, something went wrong.