import cv2
import mediapipe as mp
import numpy as np
import mss
import time

# 初始化MediaPipe Holistic
mp_drawing = mp.solutions.drawing_utils
mp_holistic = mp.solutions.holistic

# 创建Holistic检测对象
holistic = mp_holistic.Holistic(min_detection_confidence=0.5, min_tracking_confidence=0.5)

# 定义屏幕捕获区域，确保与你的屏幕分辨率相匹配
# 请根据你的屏幕分辨率调整这些值
monitor = {"top": 0, "left": 0, "width": 2880, "height": 1800}

# 定义颜色
WHITE = (255, 255, 255)
GREEN = (0, 255, 0)
RED = (0, 0, 255)
BLUE = (255, 0, 0)

# 定义骨骼连接，包括颈部连接
connections = [
    (mp_holistic.PoseLandmark.NOSE, mp_holistic.PoseLandmark.LEFT_SHOULDER),
    (mp_holistic.PoseLandmark.NOSE, mp_holistic.PoseLandmark.RIGHT_SHOULDER),
    (mp_holistic.PoseLandmark.LEFT_SHOULDER, mp_holistic.PoseLandmark.LEFT_ELBOW),
    (mp_holistic.PoseLandmark.LEFT_ELBOW, mp_holistic.PoseLandmark.LEFT_WRIST),
    (mp_holistic.PoseLandmark.RIGHT_SHOULDER, mp_holistic.PoseLandmark.RIGHT_ELBOW),
    (mp_holistic.PoseLandmark.RIGHT_ELBOW, mp_holistic.PoseLandmark.RIGHT_WRIST),
    (mp_holistic.PoseLandmark.LEFT_SHOULDER, mp_holistic.PoseLandmark.LEFT_HIP),
    (mp_holistic.PoseLandmark.RIGHT_SHOULDER, mp_holistic.PoseLandmark.RIGHT_HIP),
    (mp_holistic.PoseLandmark.LEFT_HIP, mp_holistic.PoseLandmark.LEFT_KNEE),
    (mp_holistic.PoseLandmark.LEFT_KNEE, mp_holistic.PoseLandmark.LEFT_ANKLE),
    (mp_holistic.PoseLandmark.RIGHT_HIP, mp_holistic.PoseLandmark.RIGHT_KNEE),
    (mp_holistic.PoseLandmark.RIGHT_KNEE, mp_holistic.PoseLandmark.RIGHT_ANKLE),
    # 使用NOSE和SHOULDER之间的连接来隐式表示颈部区域
    (mp_holistic.PoseLandmark.NOSE, mp_holistic.PoseLandmark.LEFT_SHOULDER),
    (mp_holistic.PoseLandmark.NOSE, mp_holistic.PoseLandmark.RIGHT_SHOULDER),
]

def capture_screen():
    """捕获屏幕内容并转换为OpenCV格式"""
    with mss.mss() as sct:
        screen = sct.grab(monitor)
        frame = np.array(screen)
        frame = cv2.cvtColor(frame, cv2.COLOR_BGRA2BGR)
    return frame

def process_image(image):
    """处理图像并绘制姿态标记"""
    image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
    image.flags.writeable = False
    results = holistic.process(image)
    image.flags.writeable = True
    image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR)
    return image, results

def draw_landmarks(image, results):
    """在图像上绘制姿态标记和身体的长方体几何框"""
    if results.pose_landmarks:
        # 绘制姿态关键点
        for id, lm in enumerate(results.pose_landmarks.landmark):
            h, w, _ = image.shape
            cx, cy = int(lm.x * w), int(lm.y * h)
            cv2.circle(image, (cx, cy), 5, GREEN, -1)

        # 绘制连接线
        for connection in connections:
            start_idx = connection[0]
            end_idx = connection[1]
            if (results.pose_landmarks.landmark[start_idx].visibility < 0.5 or
                results.pose_landmarks.landmark[end_idx].visibility < 0.5):
                continue
            start = (int(results.pose_landmarks.landmark[start_idx].x * w),
                     int(results.pose_landmarks.landmark[start_idx].y * h))
            end = (int(results.pose_landmarks.landmark[end_idx].x * w),
                   int(results.pose_landmarks.landmark[end_idx].y * h))
            cv2.line(image, start, end, RED, 2)

        # 绘制身体方框
        if results.pose_landmarks:
            left_shoulder = results.pose_landmarks.landmark[mp_holistic.PoseLandmark.LEFT_SHOULDER]
            right_shoulder = results.pose_landmarks.landmark[mp_holistic.PoseLandmark.RIGHT_SHOULDER]
            left_hip = results.pose_landmarks.landmark[mp_holistic.PoseLandmark.LEFT_HIP]
            right_hip = results.pose_landmarks.landmark[mp_holistic.PoseLandmark.RIGHT_HIP]

            body_top_left = (int(min(left_shoulder.x, right_shoulder.x) * w - 0.2 * w),
                             int(min(left_shoulder.y, left_hip.y) * h - 0.2 * h))
            body_bottom_right = (int(max(left_hip.x, right_hip.x) * w + 0.2 * w),
                                 int(max(left_hip.y, right_hip.y) * h + 0.2 * h))
            cv2.rectangle(image, body_top_left, body_bottom_right, BLUE, 2)

def calculate_fps(current_time, prev_time):
    """计算并返回FPS"""
    fps = 1 / (current_time - prev_time)
    return fps

def displayFPS(frame, fps):
    """在图像上显示FPS"""
    cv2.putText(frame, f'FPS: {int(fps)}', (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 1, WHITE, 2)

def main():
    cv2.namedWindow("Screen Detection", cv2.WINDOW_NORMAL | cv2.WINDOW_KEEPRATIO)
    cv2.setWindowProperty("Screen Detection", cv2.WND_PROP_TOPMOST, 1)    # 设置窗口为最顶层
    prev_time = time.time()

    try:
        while True:
            frame = capture_screen()
            image, results = process_image(frame)
            draw_landmarks(image, results)
            fps = calculate_fps(time.time(), prev_time)
            displayFPS(image, fps)
            cv2.imshow("Screen Detection", image)

            # 检查是否按下了'q'键
            if cv2.waitKey(1) & 0xFF == ord('q'):
                break

            prev_time = time.time()
    except Exception as e:
        print(f"An error occurred: {e}")
    finally:
        cv2.destroyAllWindows()

if __name__ == "__main__":
    main()
格式化python程序