From 2d680edaccb56ec71186fa4956a7b5bbdef2528e Mon Sep 17 00:00:00 2001 From: Mike Azatov Date: Tue, 22 Sep 2020 14:28:02 -0300 Subject: [PATCH 1/4] Update darknet_video.py The issue: Previously the output videofile had detections off by 1 frame from the video. The reason: The `darknet_image` is overwritten in `video_capture` every time it's being created because it sits in the same memory so effectively the `darknet_image_queue` is not working properly Changes: - `darknet_image` is created in every iteration of `video_capture` so every new `darknet_image` sits in different memory - remove limitations on `max_size` of the queue. I believe the limitations were put there to avoid the issue above, but it only made it so the result was off by one frame. Now that that's not an issue there is no reason to have `max_size` for any of the queques --- darknet_video.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/darknet_video.py b/darknet_video.py index de96d709ed1..753b62285d4 100644 --- a/darknet_video.py +++ b/darknet_video.py @@ -69,6 +69,7 @@ def video_capture(frame_queue, darknet_image_queue): frame_resized = cv2.resize(frame_rgb, (width, height), interpolation=cv2.INTER_LINEAR) frame_queue.put(frame_resized) + darknet_image = darknet.make_image(width, height, 3) darknet.copy_image_from_bytes(darknet_image, frame_resized.tobytes()) darknet_image_queue.put(darknet_image) cap.release() @@ -110,9 +111,9 @@ def drawing(frame_queue, detections_queue, fps_queue): if __name__ == '__main__': frame_queue = Queue() - darknet_image_queue = Queue(maxsize=1) - detections_queue = Queue(maxsize=1) - fps_queue = Queue(maxsize=1) + darknet_image_queue = Queue() + detections_queue = Queue() + fps_queue = Queue() args = parser() check_arguments_errors(args) @@ -126,7 +127,6 @@ def drawing(frame_queue, detections_queue, fps_queue): # Create one with image we reuse for each detect width = darknet.network_width(network) height = darknet.network_height(network) - darknet_image = darknet.make_image(width, height, 3) input_path = str2int(args.input) cap = cv2.VideoCapture(input_path) Thread(target=video_capture, args=(frame_queue, darknet_image_queue)).start() From 4a61d9778010a32c91ad8cd480faa4e874addf7c Mon Sep 17 00:00:00 2001 From: Mike Azatov Date: Tue, 22 Sep 2020 14:26:31 -0500 Subject: [PATCH 2/4] Put maxsize to 250 to avoid memory overload Added maxsize so there is no memory overload in case too many frames load for the detect_image. --- darknet_video.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/darknet_video.py b/darknet_video.py index 753b62285d4..f7a43820b85 100644 --- a/darknet_video.py +++ b/darknet_video.py @@ -111,9 +111,9 @@ def drawing(frame_queue, detections_queue, fps_queue): if __name__ == '__main__': frame_queue = Queue() - darknet_image_queue = Queue() - detections_queue = Queue() - fps_queue = Queue() + darknet_image_queue = Queue(maxsize = 250) + detections_queue = Queue(maxsize = 250) + fps_queue = Queue(maxsize = 250) args = parser() check_arguments_errors(args) From c788ce1c515fbcb878fd19b3d6832deceafe85ed Mon Sep 17 00:00:00 2001 From: Mike Azatov Date: Mon, 28 Sep 2020 11:12:47 -0500 Subject: [PATCH 3/4] Update darknet_video.py I was getting a memory problem because as `darknet_image` is created in every iteration of `video_capture`, it is not being released by the `darknet_image_queue` when it gets `.get()`. To fix it I make a list of darknet_images that is larger than the size of the queue. The list is being repeatedly updated with new darknet_images in `video_capture`, but the image that has not been processed yet, is never overwritten. A bit of a hacky fix, but it works. --- darknet_video.py | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/darknet_video.py b/darknet_video.py index f7a43820b85..2aa0547ed91 100644 --- a/darknet_video.py +++ b/darknet_video.py @@ -61,6 +61,7 @@ def set_saved_video(input_video, output_video, size): def video_capture(frame_queue, darknet_image_queue): + darknet_image_id = 0 while cap.isOpened(): ret, frame = cap.read() if not ret: @@ -69,9 +70,12 @@ def video_capture(frame_queue, darknet_image_queue): frame_resized = cv2.resize(frame_rgb, (width, height), interpolation=cv2.INTER_LINEAR) frame_queue.put(frame_resized) - darknet_image = darknet.make_image(width, height, 3) + darknet_image = darknet_images[darknet_image_id] darknet.copy_image_from_bytes(darknet_image, frame_resized.tobytes()) darknet_image_queue.put(darknet_image) + if darknet_image_id==maxsize-1: + darknet_image_id = 0 + darknet_image_id+=1 cap.release() @@ -111,9 +115,10 @@ def drawing(frame_queue, detections_queue, fps_queue): if __name__ == '__main__': frame_queue = Queue() - darknet_image_queue = Queue(maxsize = 250) - detections_queue = Queue(maxsize = 250) - fps_queue = Queue(maxsize = 250) + maxsize = 250 + darknet_image_queue = Queue(maxsize = maxsize-2) + detections_queue = Queue(maxsize = maxsize-2) + fps_queue = Queue(maxsize = maxsize-2) args = parser() check_arguments_errors(args) @@ -129,6 +134,10 @@ def drawing(frame_queue, detections_queue, fps_queue): height = darknet.network_height(network) input_path = str2int(args.input) cap = cv2.VideoCapture(input_path) + for i in range(maxsize): + darknet_image = darknet.make_image(width, height, 3) + darknet_images.append(darknet_image) + Thread(target=video_capture, args=(frame_queue, darknet_image_queue)).start() Thread(target=inference, args=(darknet_image_queue, detections_queue, fps_queue)).start() Thread(target=drawing, args=(frame_queue, detections_queue, fps_queue)).start() From 6a8d50663ce462770cc30d14bba621cff24389dc Mon Sep 17 00:00:00 2001 From: Mike Azatov Date: Tue, 29 Sep 2020 09:21:02 -0500 Subject: [PATCH 4/4] Update darknet_video.py Define `darknet_images` --- darknet_video.py | 1 + 1 file changed, 1 insertion(+) diff --git a/darknet_video.py b/darknet_video.py index 2aa0547ed91..111ed2db04e 100644 --- a/darknet_video.py +++ b/darknet_video.py @@ -134,6 +134,7 @@ def drawing(frame_queue, detections_queue, fps_queue): height = darknet.network_height(network) input_path = str2int(args.input) cap = cv2.VideoCapture(input_path) + darknet_images = [] for i in range(maxsize): darknet_image = darknet.make_image(width, height, 3) darknet_images.append(darknet_image)