Use `np.unique` to determine the correct set of row/col pairs to iterate
over when doing the object matching without needing to track which rows
or columns have already been seen. Add to some of the accompanying
documentation to clarify this algorithm.
Also fix what looks to be an erroneous early return, and change this to
a continue.
Generally eliminate the `while True` loops while waiting for a stop
event and prefer to condition the loops on if the stop event is set,
blocking on that where it makes sense. This generally comes in 3
flavors. First and simplest, when there is a sleep and the stop event
is the only thing the loop blocks on, instead do a check using
`stop_event.wait(timeout)` to instead block on the stop event for the
designated amount of time. Second, when there is a different event that
is blocking in the loop, condition the loop on `stop_event.is_set()`
rather than breaking when it is set. Finally, when there is a separate
internal condition that requires a counter, have the loop iterate over
the counter and use `if stop_event.wait(timeout)` internal to the loop.
When running ffprobe, use `subprocess.run` rather than
`subprocess.Popen`. This simplifies the handling that is needed to run
and process the outputs. Here, filename parsing is also simplified by
explicitly removing the file extension with `os.path.splitext` and
forcing a single split into the camera name and the formatted date.