mirror of
https://github.com/DeeJanuz/frametop.git
synced 2026-10-06 12:00:11 +02:00
ft-hands tracks with the mono IR cameras in dim light and with every camera (or the colour pair, HANDS_BRIGHT) in bright light, going by the colour frames' mean brightness with hysteresis and a 2 s hold (HANDS_CAMERAS=auto, the default; mono, color and all fix it). Colour frames are placed on the mono cameras' clock by their dequeue time, and a view in a camera a step lacks waits for that camera's next frame. A grip (a closed hand) is a second gesture next to the pinch, in version 2 of the gestures file: every fingertip curled toward the wrist, beginning only on a hand seen open within a second and held up in front. On the 2026-09-30 lit recording that leaves 6 false grips of 14, all with the hands on the desk; pinch counts are unchanged. ft-handreplay logs grips and finger curl, watch_gestures.py shows them, and tools/cut_sets.py copies a few sets out of a recording. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
52 lines
1.6 KiB
Python
52 lines
1.6 KiB
Python
"""Copy a few frame sets out of a recording (ft-hands --record) into a small one, to look at
|
|
or check elsewhere without moving gigabytes. Plain Python, so it runs on the Frame's host.
|
|
|
|
usage: python3 tools/cut_sets.py REC_DIR OUT_DIR [--sets N] (8, spread evenly) | [--at I,J,...]
|
|
"""
|
|
import argparse
|
|
import os
|
|
import struct
|
|
|
|
HDR = struct.Struct('<8sII')
|
|
|
|
|
|
def offsets(path):
|
|
offs, size = [], os.path.getsize(path)
|
|
with open(path, 'rb') as f:
|
|
off = 0
|
|
while off + HDR.size <= size:
|
|
f.seek(off)
|
|
magic, _, nbytes = HDR.unpack(f.read(HDR.size))
|
|
if magic[:7] != b'FHSET01' or off + nbytes > size:
|
|
break
|
|
offs.append((off, nbytes))
|
|
off += nbytes
|
|
return offs
|
|
|
|
|
|
def main():
|
|
ap = argparse.ArgumentParser()
|
|
ap.add_argument('rec')
|
|
ap.add_argument('out')
|
|
ap.add_argument('--sets', type=int, default=8)
|
|
ap.add_argument('--at', default='')
|
|
a = ap.parse_args()
|
|
src = os.path.join(a.rec, 'sets.bin')
|
|
offs = offsets(src)
|
|
if a.at:
|
|
pick = [int(i) for i in a.at.split(',')]
|
|
else:
|
|
n = max(1, min(a.sets, len(offs)))
|
|
pick = [round(i * (len(offs) - 1) / max(n - 1, 1)) for i in range(n)]
|
|
os.makedirs(a.out, exist_ok=True)
|
|
with open(src, 'rb') as f, open(os.path.join(a.out, 'sets.bin'), 'wb') as out:
|
|
for i in pick:
|
|
off, nbytes = offs[i]
|
|
f.seek(off)
|
|
out.write(f.read(nbytes))
|
|
print('%d of %d sets (%s) -> %s' % (len(pick), len(offs), ','.join(map(str, pick)), a.out))
|
|
|
|
|
|
if __name__ == '__main__':
|
|
main()
|