import cv2
import numpy as np
import time
import os

# 导入我们的3D手部检测模块
from src.hand_detection_3d import load_mediapipe_model, process_frame_3d

# 尝试导入 Picamera2，如果不可用则使用标准OpenCV
try:
    from picamera2 import Picamera2
    PICAMERA_AVAILABLE = True
except ImportError:
    PICAMERA_AVAILABLE = False

def process_camera_3d(camera_id=0, output_path=None, use_picamera=True):
    """
    使用摄像头进行3D手部检测 - 简化版本
    
    参数:
    camera_id: 摄像头ID (默认为0)
    output_path: 输出视频文件路径 (可选)
    use_picamera: 是否优先使用Picamera2 (树莓派摄像头)
    """
    # 加载MediaPipe手部检测模型
    hands_model = load_mediapipe_model(max_num_hands=1)
    
    # 初始化摄像头
    cap = None
    picam2 = None
    
    if use_picamera and PICAMERA_AVAILABLE:
        # 使用 Picamera2 (树莓派摄像头)
        try:
            print("正在初始化 Picamera2...")
            picam2 = Picamera2()
            video_config = picam2.create_video_configuration(main={"size": (640, 480)})
            picam2.configure(video_config)
            picam2.start()
            print("✅ Picamera2 启动成功")
            frame_width, frame_height = 640, 480
        except Exception as e:
            print(f"❌ Picamera2 启动失败: {e}")
            print("⚠️  回退到 OpenCV VideoCapture")
            picam2 = None
            use_picamera = False
    
    if not use_picamera or not PICAMERA_AVAILABLE:
        # 使用标准 OpenCV VideoCapture
        cap = cv2.VideoCapture(camera_id)
        if not cap.isOpened():
            print(f"无法打开摄像头 ID: {camera_id}")
            return
        frame_width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
        frame_height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
    
    fps = 30
    
    # 创建视频写入器（如果需要保存）
    video_writer = None
    if output_path:
        fourcc = cv2.VideoWriter_fourcc(*'XVID')
        video_writer = cv2.VideoWriter(output_path, fourcc, fps, (frame_width, frame_height))
    
    # 前一帧的手部数据
    prev_hand_data = None
    
    # 初始化性能计数器
    frame_count = 0
    start_time = time.time()
    
    print("控制说明:")
    print("- 移动手部显示控制信号")
    print("- 拇指和食指捏合显示抓取状态") 
    print("- 按 Ctrl+C 退出")
    
    try:
        while True:
            # 读取一帧
            ret = False
            frame = None
            
            if picam2:
                try:
                    frame = picam2.capture_array()
                    frame = cv2.cvtColor(frame, cv2.COLOR_RGB2BGR)
                    ret = True
                except Exception as e:
                    print(f"Picamera2 读取帧失败: {e}")
                    break
            else:
                ret, frame = cap.read()
            
            if not ret or frame is None:
                break
            
            frame_count += 1
            
            # 处理帧并获取三轴控制信号
            control_signal, prev_hand_data = process_frame_3d(frame, hands_model, prev_hand_data)
            
            # 显示控制信号
            if control_signal and frame_count % 30 == 0:  # 每秒显示一次
                print_control_signal(control_signal)
            
            # 写入输出视频
            if video_writer:
                video_writer.write(frame)
                
    except KeyboardInterrupt:
        print("\n收到中断信号，正在退出...")
    except Exception as e:
        print(f"程序运行时出错: {e}")
    finally:
        print("正在清理资源...")
        
        # 释放资源
        if picam2:
            try:
                picam2.stop()
                picam2.close()
            except:
                pass
        
        if cap:
            try:
                cap.release()
            except:
                pass
        
        if video_writer:
            try:
                video_writer.release()
                print(f"✅ 视频已保存: {output_path}")
            except:
                pass
        
        # 显示统计信息
        elapsed_time = time.time() - start_time
        if frame_count > 0:
            avg_fps = frame_count / elapsed_time
            print(f"📊 处理了 {frame_count} 帧，平均FPS: {avg_fps:.1f}")
        
        print("✅ 程序已退出")

def print_control_signal(control_signal):
    """显示手部控制信号信息"""
    print(f"手部控制信号:")
    print(f"  X轴角度: {control_signal['x_angle']:.1f}°")
    print(f"  Y轴角度: {control_signal['y_angle']:.1f}°") 
    print(f"  Z轴角度: {control_signal['z_angle']:.1f}°")
    print(f"  抓取状态: {'抓取' if control_signal['grip'] == 1 else '释放'}")
    print(f"  动作: {control_signal['action']}")
    print("-------------------------------")

if __name__ == "__main__":
    import argparse
    
    parser = argparse.ArgumentParser(description='简化版3D手部检测')
    parser.add_argument('--camera-id', '-i', type=int, default=0, help='摄像头ID (默认为0)')
    parser.add_argument('--output', '-o', help='输出视频文件路径')
    
    args = parser.parse_args()
    
    process_camera_3d(
        camera_id=args.camera_id,
        output_path=args.output
    ) 