from XEdu.hub import Workflow as wf
import cv2
import math
from unihiker import GUI
from PIL import Image

gui=GUI()

def calculate_angle(x1, y1, x2, y2):
    """计算中心点连线向量与竖直方向的夹角"""
    vector_ab = (x2 - x1, y2 - y1)
    vertical_vector = (0, 1)
    dot_product = vector_ab[0] * vertical_vector[0] + vector_ab[1] * vertical_vector[1]
    magnitude_ab = math.sqrt(vector_ab[0]**2 + vector_ab[1]**2)
    magnitude_vertical = 1  # 竖直向量的模为1，因为(0,1)的长度是1

    cos_angle = dot_product / (magnitude_ab * magnitude_vertical)
    cos_angle = min(1, max(cos_angle, -1))  # 限制范围防止计算错误

    return math.acos(cos_angle) * (180 / math.pi)

cap = cv2.VideoCapture(0)
cap.set(cv2.CAP_PROP_FRAME_WIDTH, 240)  # 设置摄像头的宽度
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 320)  # 设置摄像头的高度
cap.set(cv2.CAP_PROP_BUFFERSIZE, 1)  # 设置摄像头的缓冲区大小

bgImg=gui.draw_image(image="",x=0,y=0)
ltTxt=gui.draw_text(text="手势",x=100,y=100,font_size=28, color="#00FF00",angle = 90)

#cv2.namedWindow('Video Feed', cv2.WND_PROP_FULLSCREEN)
#cv2.setWindowProperty('Video Feed', cv2.WND_PROP_FULLSCREEN, cv2.WINDOW_FULLSCREEN)  # 设置窗口为全屏
det_face = wf(task='det_face')
det_hand = wf(task='det_hand')
num = 0
prev_flag = None

while True:
    ret, img = cap.read()
    img = cv2.flip(img, 1)#水平镜像图片
    
    if not ret:
        break

    face_result, face_with_box = det_face.inference(data=img, img_type='cv2')
    hand_result, hand_with_box = det_hand.inference(data=face_with_box, img_type='cv2')

    if face_result != [] and hand_result !=[]:
        
        fx, fy = (face_result[0][0] + face_result[0][2]) / 2, (face_result[0][1] + face_result[0][3]) / 2
        hx, hy = (hand_result[0][0] + hand_result[0][2]) / 2, (hand_result[0][1] + hand_result[0][3]) / 2
        angle = calculate_angle(fx, fy, hx, hy)

        flag = ''
        if 30 < angle < 120:
            flag = 'left' if fx > hx else 'right'
        elif angle <= 30 or angle >= 120:
            flag = 'up' if fy > hy else 'down'

        if flag == prev_flag:
            num += 1
        else:
            num = 0
            prev_flag = flag

        if num >= 5:
            print(flag)
            ltTxt.config(text=flag)
            num = 0
    img = cv2.flip(img, 0)#垂直镜像图片        
    img = cv2.rotate(img,cv2.ROTATE_90_CLOCKWISE) #旋转90度
    img= Image.fromarray(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))#将opecv图片格式转化为unihiker库图片格式
    bgImg.config(image=img)
    
    #cv2.imshow('Video Feed', hand_with_box)

    if cv2.waitKey(1) & 0xFF == 27:
        break

cap.release()
cv2.destroyAllWindows()