""" Finger UV pipeline with real-time force charts and OpenCV panels. Demonstrates: 1. UV-unrolled deformation arrows 2. Contact region overlay 3. PyQtGraph normal/shear force plots 4. Optional raw-frame recording (s/e keys) """ import argparse import os import sys import time from pathlib import Path os.environ["OPENCV_VIDEOIO_MSMF_ENABLE_HW_TRANSFORMS"] = "0" import cv2 import orisys from orisys.finger import FingerRuntime _EXAMPLES_DIR = Path(__file__).resolve().parent if str(_EXAMPLES_DIR) not in sys.path: sys.path.insert(0, str(_EXAMPLES_DIR)) from viz import ForceChartWindow, FrameRecorder, lowpass_filter def main(): parser = argparse.ArgumentParser() parser.add_argument("--video", "-v", type=str, default="0", help="视频源:摄像头编号或视频文件路径") parser.add_argument("--config", "-c", type=str, default="./config/dd02-ov.json", help="配置文件名称或路径") parser.add_argument("--verbose", "-verbose", type=bool, default=True, help="是否输出详细日志") args = parser.parse_args() charts = ForceChartWindow() recorder = FrameRecorder() runtime = FingerRuntime.open( config=args.config, video=args.video, verbose=args.verbose, ) runtime.warmup(color=True) tactile = runtime.tactile start_time = time.time() print("\n按键说明:'q' 退出程序,'s' 开始录像,'e' 结束录像。") try: while True: ok, unrolled = runtime.grab_and_process(color=True) if not ok: break recorder.write_if_recording(tactile.frame) tactile.compute_deformation(check_motion=True, threshold=0) tactile.compute_contact() fps, flow, vnormal, img, contour, centroid, depth_map, fnormal, fshearx, fsheary = tactile.read_info( tactile.info.FPS, tactile.info.VRAW, tactile.info.VNORMAL, tactile.info.IMG, tactile.info.CONTOUR, tactile.info.CENTROID, tactile.info.DEPTH, tactile.info.FNORMAL, tactile.info.FSHEARX, tactile.info.FSHEARY, ) print(f"FPS={fps:.2f}, 法向力={fnormal:.4f}, 切向力X={fshearx:.4f}, 切向力Y={fsheary:.4f}") arrows = orisys.util.draw_arrows(unrolled, flow, threshold=3, grid_spacing=10, arrow_scale=1.0) cv2.imshow("arrows", arrows) cv2.imshow("contact", orisys.util.draw_contact(img, contour, centroid)) charts.push(time.time() - start_time, fnormal, fshearx, fsheary) display = charts.data.copy() for channel in range(3): display[:, 1, channel] = lowpass_filter( charts.data[:, 1, channel], cutoff_hz=5, sample_rate_hz=30, ) charts.refresh(display) key = cv2.waitKey(1) if key & 0xFF == ord("q"): print("\n正在退出示例程序...") break if key == ord("s"): recorder.start(tactile.frame) if key == ord("e"): recorder.stop() finally: runtime.close() if __name__ == "__main__": main()