Multiple sources can now be used
Added `--fake-second-source` to help with debugging
This commit is contained in:
parent
494708a376
commit
8f500e0186
|
@ -10,7 +10,7 @@
|
||||||
"request": "launch",
|
"request": "launch",
|
||||||
"module": "wyzely_detect",
|
"module": "wyzely_detect",
|
||||||
"args": [
|
"args": [
|
||||||
"--run-scale", "0.25", "--view-scale", "0.5", "--no-remove-representations"
|
"--run-scale", "0.25", "--view-scale", "0.5", "--no-remove-representations", "--fake-second-source"
|
||||||
],
|
],
|
||||||
"justMyCode": true
|
"justMyCode": true
|
||||||
},
|
},
|
||||||
|
|
|
@ -59,6 +59,17 @@ def main():
|
||||||
"devices": [cv2.VideoCapture(device) for device in args.capture_device],
|
"devices": [cv2.VideoCapture(device) for device in args.capture_device],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if args.fake_second_source:
|
||||||
|
try:
|
||||||
|
video_sources["devices"].append(video_sources["devices"][0])
|
||||||
|
except KeyError:
|
||||||
|
print("No capture device to use as second source. Trying stream.")
|
||||||
|
try:
|
||||||
|
video_sources["devices"].append(video_sources["devices"][0])
|
||||||
|
except KeyError:
|
||||||
|
print("No stream to use as a second source")
|
||||||
|
# When the code tries to resize the nonexistent capture device 1, the program will fail
|
||||||
|
|
||||||
# Eliminate lag by setting the buffer size to 1
|
# Eliminate lag by setting the buffer size to 1
|
||||||
# This makes it so that the video capture will only grab the most recent frame
|
# This makes it so that the video capture will only grab the most recent frame
|
||||||
# However, this means that the video may be choppy
|
# However, this means that the video may be choppy
|
||||||
|
@ -74,6 +85,7 @@ def main():
|
||||||
pretty_table = PrettyTable(field_names=["Source Type", "Resolution"])
|
pretty_table = PrettyTable(field_names=["Source Type", "Resolution"])
|
||||||
for source_type, sources in video_sources.items():
|
for source_type, sources in video_sources.items():
|
||||||
for source in sources:
|
for source in sources:
|
||||||
|
# TODO: Add check to see if resolution is 0x0, and if it is, print a warning or just fail
|
||||||
pretty_table.add_row(
|
pretty_table.add_row(
|
||||||
[source_type, f"{source.get(cv2.CAP_PROP_FRAME_WIDTH)}x{source.get(cv2.CAP_PROP_FRAME_HEIGHT)}"]
|
[source_type, f"{source.get(cv2.CAP_PROP_FRAME_WIDTH)}x{source.get(cv2.CAP_PROP_FRAME_HEIGHT)}"]
|
||||||
)
|
)
|
||||||
|
@ -83,31 +95,36 @@ def main():
|
||||||
print("Beginning video capture...")
|
print("Beginning video capture...")
|
||||||
while True:
|
while True:
|
||||||
# Grab a single frame of video
|
# Grab a single frame of video
|
||||||
ret, frame = video_capture.read()
|
frames = []
|
||||||
|
# frames = [source.read() for sources in video_sources.values() for source in sources]
|
||||||
|
for list_of_sources in video_sources.values():
|
||||||
|
frames.extend([source.read()[1] for source in list_of_sources])
|
||||||
|
frames_to_show = []
|
||||||
|
for frame in frames:
|
||||||
|
frames_to_show.append(utils.process_footage(
|
||||||
|
frame = frame,
|
||||||
|
run_scale = args.run_scale,
|
||||||
|
view_scale = args.view_scale,
|
||||||
|
|
||||||
frame_to_show = utils.process_footage(
|
faces_directory=Path(args.faces_directory),
|
||||||
frame = frame,
|
face_confidence_threshold=args.face_confidence_threshold,
|
||||||
run_scale = args.run_scale,
|
no_remove_representations=args.no_remove_representations,
|
||||||
view_scale = args.view_scale,
|
|
||||||
|
|
||||||
faces_directory=Path(args.faces_directory),
|
detection_window=args.detection_window,
|
||||||
face_confidence_threshold=args.face_confidence_threshold,
|
detection_duration=args.detection_duration,
|
||||||
no_remove_representations=args.no_remove_representations,
|
notification_window=args.notification_window,
|
||||||
|
|
||||||
detection_window=args.detection_window,
|
ntfy_url=args.ntfy_url,
|
||||||
detection_duration=args.detection_duration,
|
|
||||||
notification_window=args.notification_window,
|
|
||||||
|
|
||||||
ntfy_url=args.ntfy_url,
|
model=model,
|
||||||
|
detect_object=args.detect_object,
|
||||||
model=model,
|
object_confidence_threshold=args.object_confidence_threshold,
|
||||||
detect_object=args.detect_object,
|
))
|
||||||
object_confidence_threshold=args.object_confidence_threshold,
|
|
||||||
)
|
|
||||||
# Display the resulting frame
|
# Display the resulting frame
|
||||||
# TODO: When multi-camera support is added, this needs to be changed to allow all feeds
|
# TODO: When multi-camera support is added, this needs to be changed to allow all feeds
|
||||||
if not args.no_display:
|
if not args.no_display:
|
||||||
cv2.imshow("Video", frame_to_show)
|
for i, frame_to_show in enumerate(frames_to_show):
|
||||||
|
cv2.imshow(f"Video {i}", frame_to_show)
|
||||||
|
|
||||||
# Hit 'q' on the keyboard to quit!
|
# Hit 'q' on the keyboard to quit!
|
||||||
if cv2.waitKey(1) & 0xFF == ord("q"):
|
if cv2.waitKey(1) & 0xFF == ord("q"):
|
||||||
|
@ -115,7 +132,7 @@ def main():
|
||||||
|
|
||||||
# Release handle to the webcam
|
# Release handle to the webcam
|
||||||
print("Releasing video capture")
|
print("Releasing video capture")
|
||||||
video_capture.release()
|
[source.release() for sources in video_sources.values() for source in sources]
|
||||||
cv2.destroyAllWindows()
|
cv2.destroyAllWindows()
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,7 @@ def set_argparse():
|
||||||
argparser = argparse.ArgumentParser(
|
argparser = argparse.ArgumentParser(
|
||||||
prog="Wyzely Detect",
|
prog="Wyzely Detect",
|
||||||
description="Recognize faces/objects in a video stream (from a webcam or a security camera) and send notifications to your devices", # noqa: E501
|
description="Recognize faces/objects in a video stream (from a webcam or a security camera) and send notifications to your devices", # noqa: E501
|
||||||
epilog=":)",
|
epilog="For env bool options, setting them to anything except for an empty string will enable them."
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -69,7 +69,9 @@ def set_argparse():
|
||||||
video_options.add_argument(
|
video_options.add_argument(
|
||||||
"--no-display",
|
"--no-display",
|
||||||
default=os.environ["NO_DISPLAY"]
|
default=os.environ["NO_DISPLAY"]
|
||||||
if "NO_DISPLAY" in os.environ and os.environ["NO_DISPLAY"] != ""
|
if "NO_DISPLAY" in os.environ
|
||||||
|
and os.environ["NO_DISPLAY"] != ""
|
||||||
|
and os.environ["NO_DISPLAY"].lower() != "false"
|
||||||
else False,
|
else False,
|
||||||
action="store_true",
|
action="store_true",
|
||||||
help="Don't display the video feed",
|
help="Don't display the video feed",
|
||||||
|
@ -78,7 +80,9 @@ def set_argparse():
|
||||||
'-c',
|
'-c',
|
||||||
'--force-disable-tensorflow-gpu',
|
'--force-disable-tensorflow-gpu',
|
||||||
default=os.environ["FORCE_DISABLE_TENSORFLOW_GPU"]
|
default=os.environ["FORCE_DISABLE_TENSORFLOW_GPU"]
|
||||||
if "FORCE_DISABLE_TENSORFLOW_GPU" in os.environ and os.environ["FORCE_DISABLE_TENSORFLOW_GPU"] != ""
|
if "FORCE_DISABLE_TENSORFLOW_GPU" in os.environ
|
||||||
|
and os.environ["FORCE_DISABLE_TENSORFLOW_GPU"] != ""
|
||||||
|
and os.environ["FORCE_DISABLE_TENSORFLOW_GPU"].lower() != "false"
|
||||||
else False,
|
else False,
|
||||||
action="store_true",
|
action="store_true",
|
||||||
help="Force disable tensorflow GPU through env since sometimes it's not worth it to install cudnn and whatnot",
|
help="Force disable tensorflow GPU through env since sometimes it's not worth it to install cudnn and whatnot",
|
||||||
|
@ -146,6 +150,7 @@ def set_argparse():
|
||||||
default=os.environ["NO_REMOVE_REPRESENTATIONS"]
|
default=os.environ["NO_REMOVE_REPRESENTATIONS"]
|
||||||
if "NO_REMOVE_REPRESENTATIONS" in os.environ
|
if "NO_REMOVE_REPRESENTATIONS" in os.environ
|
||||||
and os.environ["NO_REMOVE_REPRESENTATIONS"] != ""
|
and os.environ["NO_REMOVE_REPRESENTATIONS"] != ""
|
||||||
|
and os.environ["NO_REMOVE_REPRESENTATIONS"].lower() != "false"
|
||||||
else False,
|
else False,
|
||||||
action="store_true",
|
action="store_true",
|
||||||
help="Don't remove representations_<model>.pkl at the start of the program. Greatly improves startup time, but doesn't take into account changes to the faces directory since it was created", # noqa: E501
|
help="Don't remove representations_<model>.pkl at the start of the program. Greatly improves startup time, but doesn't take into account changes to the faces directory since it was created", # noqa: E501
|
||||||
|
@ -166,12 +171,27 @@ def set_argparse():
|
||||||
"--object-confidence-threshold",
|
"--object-confidence-threshold",
|
||||||
default=os.environ["OBJECT_CONFIDENCE_THRESHOLD"]
|
default=os.environ["OBJECT_CONFIDENCE_THRESHOLD"]
|
||||||
if "OBJECT_CONFIDENCE_THRESHOLD" in os.environ
|
if "OBJECT_CONFIDENCE_THRESHOLD" in os.environ
|
||||||
and os.environ["OBJECT_CONFIDENCE_THRESHOLD"] != ""
|
and os.environ["OBJECT_CONFIDENCE_THRESHOLD"] != ""
|
||||||
|
# I think this should always be a str so using lower shouldn't be a problem.
|
||||||
|
# Also, if the first check fails the rest shouldn't be run
|
||||||
|
and os.environ["OBJECT_CONFIDENCE_THRESHOLD"].lower() != "false"
|
||||||
else 0.6,
|
else 0.6,
|
||||||
type=float,
|
type=float,
|
||||||
help="The confidence threshold to use",
|
help="The confidence threshold to use",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
debug = argparser.add_argument_group("Debug options")
|
||||||
|
debug.add_argument(
|
||||||
|
"--fake-second-source",
|
||||||
|
help="Duplicate the first source and use it as a second source. Capture device takes priority.",
|
||||||
|
action="store_true",
|
||||||
|
default=os.environ["FAKE_SECOND_SOURCE"]
|
||||||
|
if "FAKE_SECOND_SOURCE" in os.environ
|
||||||
|
and os.environ["FAKE_SECOND_SOURCE"] != ""
|
||||||
|
and os.environ["FAKE_SECOND_SOURCE"].lower() != "false"
|
||||||
|
else False,
|
||||||
|
)
|
||||||
|
|
||||||
# return argparser
|
# return argparser
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue