diff --git a/.gitignore b/.gitignore index fda7dbf..b45d290 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,4 @@ tf_models/ -*.csv \ No newline at end of file +*.csv +*.mp4 +__pycache__/ \ No newline at end of file diff --git a/analytics/__pycache__/tracking.cpython-36.pyc b/analytics/__pycache__/tracking.cpython-36.pyc index 4947a22..ac28ea2 100644 Binary files a/analytics/__pycache__/tracking.cpython-36.pyc and b/analytics/__pycache__/tracking.cpython-36.pyc differ diff --git a/analytics/tracking.py b/analytics/tracking.py index 8a0c926..60eef4f 100644 --- a/analytics/tracking.py +++ b/analytics/tracking.py @@ -34,7 +34,7 @@ def update_person_status(self, class_names): def write_to_report(self, frame_number): - self.writer.writerow({'frame': frame_number, 'detections': self.class_names}) + self.writer.writerow({'frame': frame_number, 'detections': self.class_counts}) def __call__(self, context): diff --git a/detect_object.py b/detect_object.py new file mode 100644 index 0000000..902a503 --- /dev/null +++ b/detect_object.py @@ -0,0 +1,42 @@ +import os +import numpy as np +from utils import label_map_util +from utils.webcam import draw_boxes_and_labels + + +CWD_PATH = os.getcwd() +PATH_TO_LABELS = os.path.join(CWD_PATH, 'detection', 'data', 'mscoco_label_map.pbtxt') + +NUM_CLASSES = 90 +# label map +label_map = label_map_util.load_labelmap(PATH_TO_LABELS) +categories = label_map_util.convert_label_map_to_categories(label_map, max_num_classes=NUM_CLASSES, + use_display_name=True) +category_index = label_map_util.create_category_index(categories) + +# pass in image_np, returns +def detect_objects(image_np, sess, detection_graph): + + image_np_expanded = np.expand_dims(image_np, axis=0) + image_tensor = detection_graph.get_tensor_by_name('image_tensor:0') + + boxes = detection_graph.get_tensor_by_name('detection_boxes:0') + + scores = detection_graph.get_tensor_by_name('detection_scores:0') + classes = detection_graph.get_tensor_by_name('detection_classes:0') + num_detections = detection_graph.get_tensor_by_name('num_detections:0') + + # Do the detection/model prediction here + (boxes, scores, classes, num_detections) = sess.run( + [boxes, scores, classes, num_detections], + feed_dict={image_tensor: image_np_expanded}) + + rect_points, class_names, class_colors = draw_boxes_and_labels( + boxes=np.squeeze(boxes), + classes=np.squeeze(classes).astype(np.int32), + scores=np.squeeze(scores), + category_index=category_index, + min_score_thresh=.5 + ) + + return dict(rect_points=rect_points, class_names=class_names, class_colors=class_colors) \ No newline at end of file diff --git a/objection_detection_app.py b/objection_detection_app.py index 491b602..c267182 100644 --- a/objection_detection_app.py +++ b/objection_detection_app.py @@ -5,11 +5,12 @@ import numpy as np import tensorflow as tf -from utils.webcam import FPS, WebcamVideoStream, draw_boxes_and_labels +from utils.webcam import FPS, WebcamVideoStream from queue import Queue from threading import Thread -from utils import label_map_util from analytics.tracking import ObjectTracker +from video_writer import VideoWriter +from detect_object import detect_objects CWD_PATH = os.getcwd() @@ -17,49 +18,6 @@ PATH_TO_MODEL = os.path.join(CWD_PATH, 'detection', 'tf_models', MODEL_NAME, 'frozen_inference_graph.pb') PATH_TO_VIDEO = os.path.join(CWD_PATH, 'input.mp4') -print('cv2', cv2.__version__) - -PATH_TO_LABELS = os.path.join(CWD_PATH, 'detection', 'data', 'mscoco_label_map.pbtxt') - -NUM_CLASSES = 90 - -# label map -label_map = label_map_util.load_labelmap(PATH_TO_LABELS) -categories = label_map_util.convert_label_map_to_categories(label_map, max_num_classes=NUM_CLASSES, - use_display_name=True) -category_index = label_map_util.create_category_index(categories) - -# pass in image_np, returns -def detect_objects(image_np, sess, detection_graph): - - image_np_expanded = np.expand_dims(image_np, axis=0) - # print('image_np_expanded') - # print(image_np) - image_tensor = detection_graph.get_tensor_by_name('image_tensor:0') - - boxes = detection_graph.get_tensor_by_name('detection_boxes:0') - - scores = detection_graph.get_tensor_by_name('detection_scores:0') - classes = detection_graph.get_tensor_by_name('detection_classes:0') - num_detections = detection_graph.get_tensor_by_name('num_detections:0') - - # Do the detection/model prediction here - (boxes, scores, classes, num_detections) = sess.run( - [boxes, scores, classes, num_detections], - feed_dict={image_tensor: image_np_expanded}) - - # print('num_detections:', num_detections) - # Visualization of the results of a detection. - # print('classes:', classes) - rect_points, class_names, class_colors = draw_boxes_and_labels( - boxes=np.squeeze(boxes), - classes=np.squeeze(classes).astype(np.int32), - scores=np.squeeze(scores), - category_index=category_index, - min_score_thresh=.5 - ) - - return dict(rect_points=rect_points, class_names=class_names, class_colors=class_colors) def worker(input_q, output_q): # load the frozen tensorflow model into memory @@ -104,6 +62,7 @@ def worker(input_q, output_q): video_capture = WebcamVideoStream(src=args.video_source, width=args.width, height=args.height).start() + writer = VideoWriter('output.mp4', (args.width, args.height)) ''' stream = cv2.VideoCapture(0) @@ -131,8 +90,9 @@ def worker(input_q, output_q): else: data = output_q.get() context = {'frame': frame, 'class_names': data['class_names'], 'rec_points': data['rect_points'], 'class_colors': data['class_colors'], - 'width': args.width, 'height': args.height, 'frame_numer': fps.get_numFrames()} + 'width': args.width, 'height': args.height, 'frame_number': fps.get_numFrames()} new_frame = object_tracker(context) + writer(new_frame) cv2.imshow('Video', new_frame) print('[INFO] elapsed time: {:.2f}'.format(time.time() - t)) @@ -145,4 +105,5 @@ def worker(input_q, output_q): print('[INFO] approx. FPS: {:.2f}'.format(fps.fps())) video_capture.stop() + writer.close() cv2.destroyAllWindows() diff --git a/utils/__pycache__/visualization.cpython-36.pyc b/utils/__pycache__/visualization.cpython-36.pyc deleted file mode 100644 index c5ce605..0000000 Binary files a/utils/__pycache__/visualization.cpython-36.pyc and /dev/null differ diff --git a/utils/__pycache__/webcam.cpython-36.pyc b/utils/__pycache__/webcam.cpython-36.pyc index 10b13d0..e6ade01 100644 Binary files a/utils/__pycache__/webcam.cpython-36.pyc and b/utils/__pycache__/webcam.cpython-36.pyc differ diff --git a/utils/webcam.py b/utils/webcam.py index 8fb43bc..9856af6 100644 --- a/utils/webcam.py +++ b/utils/webcam.py @@ -78,6 +78,7 @@ def read(self): def stop(self): # stopping the thread self.stopped = True + self.stream.release() def standard_colors(): diff --git a/video_writer.py b/video_writer.py new file mode 100644 index 0000000..e75bacb --- /dev/null +++ b/video_writer.py @@ -0,0 +1,19 @@ +import cv2 + +class VideoWriter(object): + + def __init__(self, path, size): + self.path = path + self.size = size + self.writer = cv2.VideoWriter(self.path, + cv2.VideoWriter_fourcc('M','J','P','G'), + 20.0, self.size, True) + + def __call__(self, frame): + self.writer.write(frame) + + def close(): + self.writer.release() + + +