65 lines
2.5 KiB
Python
65 lines
2.5 KiB
Python
"""Record serial detections and reconstruct diagnostic JPEGs from the camera."""
|
|
|
|
import argparse
|
|
import pathlib
|
|
import time
|
|
|
|
import serial
|
|
|
|
|
|
def main() -> None:
|
|
parser = argparse.ArgumentParser(description=__doc__)
|
|
parser.add_argument("--port", default="/dev/cu.usbmodem1101")
|
|
parser.add_argument("--seconds", type=float, default=30)
|
|
parser.add_argument("--name", default="person-detector-diagnostic")
|
|
args = parser.parse_args()
|
|
|
|
output = pathlib.Path(__file__).resolve().parents[2] / "hardware/camera-captures"
|
|
output.mkdir(parents=True, exist_ok=True)
|
|
log_path = output / f"{args.name}.log"
|
|
frame_number = None
|
|
expected_length = 0
|
|
hex_lines: list[str] = []
|
|
detections = 0
|
|
lines: list[str] = []
|
|
|
|
with serial.Serial(args.port, 115200, timeout=0.5) as port:
|
|
deadline = time.monotonic() + args.seconds
|
|
while time.monotonic() < deadline:
|
|
raw = port.readline()
|
|
if not raw:
|
|
continue
|
|
line = raw.decode("utf-8", "replace").strip()
|
|
lines.append(line)
|
|
if "freddy_person: PERSON " in line:
|
|
detections += 1
|
|
print(line, flush=True)
|
|
elif "freddy_person: NO_PERSON " in line and len(lines) % 20 == 0:
|
|
print(line, flush=True)
|
|
|
|
if line.startswith("FRAME_BEGIN "):
|
|
_, number, length = line.split()
|
|
frame_number = int(number)
|
|
expected_length = int(length)
|
|
hex_lines = []
|
|
elif line.startswith("FRAME_HEX ") and frame_number is not None:
|
|
hex_lines.append(line.removeprefix("FRAME_HEX "))
|
|
elif line.startswith("FRAME_END ") and frame_number is not None:
|
|
number = int(line.split()[1])
|
|
if number == frame_number:
|
|
data = bytes.fromhex("".join(hex_lines))
|
|
if len(data) == expected_length and data.startswith(b"\xff\xd8") and data.endswith(b"\xff\xd9"):
|
|
photo = output / f"{args.name}-frame-{number}.jpg"
|
|
photo.write_bytes(data)
|
|
print(f"Saved {photo} ({len(data)} bytes)", flush=True)
|
|
else:
|
|
print(f"Incomplete frame {number}: {len(data)}/{expected_length} bytes", flush=True)
|
|
frame_number = None
|
|
|
|
log_path.write_text("\n".join(lines) + "\n")
|
|
print(f"Saved {log_path}; {detections} person detections", flush=True)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|