File size: 3,527 Bytes
e2d95ed
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
#!/usr/bin/env python3
"""
Webcam readiness check.

Answers "why is the camera not working?" with measurements instead of guesses:

    python scripts/camera_check.py             # or: python run.py camera
    python scripts/camera_check.py --indices 0 1 2 3 4 --capture md_out.txt

Exit codes: 0 = a camera is usable, 1 = no camera (with the reason printed),
2 = no camera *and* no display (i.e. this is a headless machine).

The check is read-only: it opens each device briefly, reads two frames, releases it,
and (optionally) runs the MediaPipe extractor on one frame to confirm the whole
capture -> landmarks path works here.
"""

from __future__ import annotations

import argparse
import sys
from pathlib import Path

sys.path.insert(0, str(Path(__file__).resolve().parents[1]))

import config  # noqa: E402
from backend.inference import camera as camera_utils  # noqa: E402


def main(argv=None) -> int:
    ap = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter)
    ap.add_argument("--indices", nargs="*", type=int, default=None,
                    help=f"indices to test (default 0..{config.CAMERA_PROBE_MAX_INDEX})")
    ap.add_argument("--no-extractor", action="store_true",
                    help="skip the MediaPipe end-to-end check")
    args = ap.parse_args(argv)

    rep = camera_utils.report(indices=args.indices)

    print("Webcam readiness check")
    print("=" * 72)
    print(f"  platform            : {rep.platform}")
    print(f"  capture devices     : {rep.device_nodes or 'none (/dev/video* absent)'}")
    print(f"  DISPLAY             : {rep.display or '<unset>'}")
    print(f"  OpenCV GUI backend  : {rep.opencv_gui_backend}")
    print(f"  preview window      : {rep.gui_available}  ({rep.gui_note})")
    print("  capture probes:")
    for probe in rep.probes:
        mark = "OK   " if probe.readable else "--   "
        print(f"    [{mark}] index {probe.index}: opened={probe.opened} readable={probe.readable} "
              f"shape={probe.shape} fps={probe.fps:.1f} {probe.error}")

    if rep.usable and not args.no_extractor:
        print("  MediaPipe end-to-end check:")
        try:
            import cv2

            from backend.preprocessing.mediapipe_extractor import MediaPipeExtractor

            cap, _, _ = camera_utils.open_camera(preferred_index=rep.usable_index)
            assert cap is not None
            ok, frame = cap.read()
            cap.release()
            if ok:
                extractor = MediaPipeExtractor()
                try:
                    lm = extractor.extract_frame(cv2.cvtColor(frame, cv2.COLOR_BGR2RGB), timestamp_ms=1)
                    print(f"    pose={lm.pose is not None} left_hand={lm.left_hand is not None} "
                          f"right_hand={lm.right_hand is not None}")
                    if lm.is_empty():
                        print("    nothing detected in that frame - make sure a person is in view; "
                              "this is a detection issue, not a camera issue")
                finally:
                    extractor.close()
        except Exception as exc:
            print(f"    extractor check failed: {type(exc).__name__}: {exc}")

    print("-" * 72)
    for hint in rep.diagnosis():
        print(f" * {hint}")

    if not rep.usable:
        print()
        print(camera_utils.no_camera_help())

    if rep.usable:
        return 0
    return 2 if not rep.gui_available else 1


if __name__ == "__main__":
    raise SystemExit(main())