python,食指操作翻页

<<< 向左挥动: 后退
<<< 向左挥动: 后退
<<< 向左挥动: 后退

向右挥动: 前进
<<< 向左挥动: 后退
<<< 向左挥动: 后退
<<< 向左挥动: 后退
<<< 向左挥动: 后退
<<< 向左挥动: 后退
向右挥动: 前进
向右挥动: 前进
向右挥动: 前进
向右挥动: 前进
向右挥动: 前进
向右挥动: 前进
向右挥动: 前进
<<< 向左挥动: 后退
向右挥动: 前进
向右挥动: 前进
向右挥动: 前进
向右挥动: 前进
向右挥动: 前进
<<< 向左挥动: 后退
<<< 向左挥动: 后退

import cv2
import mediapipe as mp
import pyautogui
import time
import math

# ================= 配置区域 =================
# 动作灵敏度 (0.05 - 0.2 之间,越小越灵敏)
SWIPE_THRESHOLD = 0.10
# 两次动作之间的冷却时间 (秒),防止一次挥动触发多次翻页
COOLDOWN_TIME = 1.0
# 浏览器快捷键映射
KEY_BACK = ['alt', 'left']  # Chrome 后退 (上一页)
KEY_FORWARD = ['alt', 'right']  # Chrome 前进 (下一页)


# ===========================================

class HandController:
    def __init__(self):
        # 初始化 MediaPipe Hands
        self.mp_hands = mp.solutions.hands
        self.hands = self.mp_hands.Hands(
            max_num_hands=1,
            min_detection_confidence=0.7,
            min_tracking_confidence=0.7
        )
        self.mp_draw = mp.solutions.drawing_utils

        # 状态变量
        self.prev_x = None  # 上一帧的食指尖 X 坐标
        self.last_action_time = 0  # 上次触发动作的时间
        self.action_text = ""  # 屏幕上显示的提示文字
        self.action_display_timer = 0  # 文字显示计时器

    def detect_gesture(self, landmarks):
        """
        检测挥动手势
        landmarks: 手部关键点列表
        """
        current_time = time.time()

        # 获取食指指尖 (关键点 8) 的 X 坐标 (范围 0.0 - 1.0)
        # 0.0 是屏幕左侧,1.0 是屏幕右侧
        index_finger_tip = landmarks.landmark[8]
        curr_x = index_finger_tip.x

        # 如果还在冷却时间内,只更新坐标,不触发动作
        if current_time - self.last_action_time < COOLDOWN_TIME:
            self.prev_x = curr_x
            return

        if self.prev_x is not None:
            # 计算移动距离
            diff_x = curr_x - self.prev_x

            # 判断移动幅度和方向
            # 向右挥动 (diff_x > 0) -> 前进
            if diff_x > SWIPE_THRESHOLD:
                print(">>> 向右挥动: 前进")
                pyautogui.hotkey(*KEY_FORWARD)
                self.last_action_time = current_time
                self.action_text = "Next Page >"
                self.action_display_timer = 30  # 显示约1秒(30帧)

            # 向左挥动 (diff_x < 0) -> 后退
            elif diff_x < -SWIPE_THRESHOLD:
                print("<<< 向左挥动: 后退")
                pyautogui.hotkey(*KEY_BACK)
                self.last_action_time = current_time
                self.action_text = "< Previous Page"
                self.action_display_timer = 30

        # 更新上一帧坐标
        self.prev_x = curr_x

    def start(self):
        # 打开摄像头
        cap = cv2.VideoCapture(0)
        # 设置分辨率 (降低分辨率可以提高处理速度)
        cap.set(3, 640)
        cap.set(4, 480)

        print("程序已启动!请将焦点切换到 Google Chrome 浏览器。")
        print("操作说明: 食指快速向左挥动 -> 后退,向右挥动 -> 前进")
        print("按 'q' 键退出程序")

        while True:
            success, img = cap.read()
            if not success:
                break

            # 1. 镜像翻转图像 (让画面看起来像照镜子,符合直觉)
            img = cv2.flip(img, 1)

            # 2. 转换颜色空间 BGR -> RGB
            img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)

            # 3. 处理手部检测
            results = self.hands.process(img_rgb)

            if results.multi_hand_landmarks:
                for hand_lms in results.multi_hand_landmarks:
                    # 绘制手部骨架
                    self.mp_draw.draw_landmarks(img, hand_lms, self.mp_hands.HAND_CONNECTIONS)

                    # 检测手势
                    self.detect_gesture(hand_lms)
            else:
                # 如果没检测到手,重置位置,防止手重新出现时误判
                self.prev_x = None

            # 4. 在屏幕上显示反馈文字
            if self.action_display_timer > 0:
                cv2.putText(img, self.action_text, (50, 50),
                            cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 3)
                self.action_display_timer -= 1

            # 显示冷却状态
            if time.time() - self.last_action_time < COOLDOWN_TIME:
                cv2.circle(img, (30, 30), 10, (0, 0, 255), -1)  # 红点表示冷却中
            else:
                cv2.circle(img, (30, 30), 10, (0, 255, 0), -1)  # 绿点表示就绪

            # 显示图像
            cv2.imshow("Chrome Hand Controller", img)

            # 按 'q' 退出
            if cv2.waitKey(1) & 0xFF == ord('q'):
                break

        cap.release()
        cv2.destroyAllWindows()


if __name__ == "__main__":
    controller = HandController()
    controller.start()
import cv2
import mediapipe as mp
import pyautogui
import time
import numpy as np

# ================= 配置区域 =================
# 动作灵敏度 (0.05 - 0.2 之间,越小越灵敏)
SWIPE_THRESHOLD = 0.07
# 两次动作之间的冷却时间 (秒),防止一次挥动触发多次翻页
COOLDOWN_TIME = 1.0
# 浏览器快捷键映射
KEY_BACK = ['alt', 'left']  # Chrome 后退 (上一页)
KEY_FORWARD = ['alt', 'right']  # Chrome 前进 (下一页)


# ===========================================

class HandController:
    def __init__(self):
        # 初始化 MediaPipe Hands
        self.mp_hands = mp.solutions.hands
        self.hands = self.mp_hands.Hands(
            max_num_hands=1,
            min_detection_confidence=0.7,
            min_tracking_confidence=0.7
        )
        self.mp_draw = mp.solutions.drawing_utils

        # 状态变量
        self.prev_x = None  # 上一帧的食指尖 X 坐标
        self.last_action_time = 0  # 上次触发动作的时间
        self.action_text = ""  # 屏幕上显示的提示文字
        self.action_display_timer = 0  # 文字显示计时器

    def detect_gesture(self, landmarks):
        """
        检测挥动手势
        landmarks: 手部关键点列表
        """
        current_time = time.time()

        # 获取食指指尖 (关键点 8) 的 X 坐标 (范围 0.0 - 1.0)
        # 0.0 是屏幕左侧,1.0 是屏幕右侧
        index_finger_tip = landmarks.landmark[8]
        curr_x = index_finger_tip.x

        # 如果还在冷却时间内,只更新坐标,不触发动作
        if current_time - self.last_action_time < COOLDOWN_TIME:
            self.prev_x = curr_x
            return

        if self.prev_x is not None:
            # 计算移动距离
            diff_x = curr_x - self.prev_x

            # 判断移动幅度和方向
            # 向右挥动 (diff_x > 0) -> 前进
            if diff_x > SWIPE_THRESHOLD:
                print(">>> 向右挥动: 前进")
                pyautogui.hotkey(*KEY_FORWARD)
                self.last_action_time = current_time
                self.action_text = "Next Page >"
                self.action_display_timer = 30  # 显示约1秒(30帧)

            # 向左挥动 (diff_x < 0) -> 后退
            elif diff_x < -SWIPE_THRESHOLD:
                print("<<< 向左挥动: 后退")
                pyautogui.hotkey(*KEY_BACK)
                self.last_action_time = current_time
                self.action_text = "< Previous Page"
                self.action_display_timer = 30

        # 更新上一帧坐标
        self.prev_x = curr_x

    def start(self):
        # 打开摄像头
        cap = cv2.VideoCapture(0)
        # 设置分辨率 (降低分辨率可以提高处理速度)
        cap.set(3, 640)
        cap.set(4, 480)

        print("程序已启动!请将焦点切换到 Google Chrome 浏览器。")
        print("操作说明: 食指快速向左挥动 -> 后退,向右挥动 -> 前进")
        print("按 'q' 键退出程序")

        while True:
            success, img = cap.read()
            if not success:
                break

            # 1. 镜像翻转图像 (让画面看起来像照镜子,符合直觉)
            img = cv2.flip(img, 1)

            # 2. 创建一个纯色背景(黑色)
            height, width = img.shape[:2]
            display_img = np.zeros((height, width, 3), dtype=np.uint8)  # 黑色背景

            # 3. 转换颜色空间 BGR -> RGB
            img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)

            # 4. 处理手部检测
            results = self.hands.process(img_rgb)

            if results.multi_hand_landmarks:
                for hand_lms in results.multi_hand_landmarks:
                    # 在黑色背景上绘制手部骨架
                    self.mp_draw.draw_landmarks(
                        display_img,
                        hand_lms,
                        self.mp_hands.HAND_CONNECTIONS,
                        landmark_drawing_spec=mp.solutions.drawing_utils.DrawingSpec(
                            color=(0, 255, 0), thickness=2  # 关键点为绿色
                        ),
                        connection_drawing_spec=mp.solutions.drawing_utils.DrawingSpec(
                            color=(255, 0, 0), thickness=2  # 连接线为蓝色
                        )
                    )

                    # 检测手势
                    self.detect_gesture(hand_lms)
            else:
                # 如果没检测到手,重置位置,防止手重新出现时误判
                self.prev_x = None

            # 5. 在屏幕上显示反馈文字
            if self.action_display_timer > 0:
                cv2.putText(display_img, self.action_text, (50, 50),
                            cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 3)
                self.action_display_timer -= 1

            # 显示冷却状态
            if time.time() - self.last_action_time < COOLDOWN_TIME:
                cv2.circle(display_img, (30, 30), 10, (0, 0, 255), -1)  # 红点表示冷却中
                cv2.putText(display_img, "Cooling", (10, 60),
                           cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 2)
            else:
                cv2.circle(display_img, (30, 30), 10, (0, 255, 0), -1)  # 绿点表示就绪
                cv2.putText(display_img, "Ready", (10, 60),
                           cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 2)

            # 显示操作提示
            cv2.putText(display_img, "Swipe Left: Back", (width-200, 30),
                       cv2.FONT_HERSHEY_SIMPLEX, 0.6, (255, 255, 255), 2)
            cv2.putText(display_img, "Swipe Right: Forward", (width-200, 60),
                       cv2.FONT_HERSHEY_SIMPLEX, 0.6, (255, 255, 255), 2)
            cv2.putText(display_img, "Press 'q' to quit", (width-200, 90),
                       cv2.FONT_HERSHEY_SIMPLEX, 0.6, (255, 255, 255), 2)

            # 显示图像(只有手部骨架在黑色背景上)
            cv2.imshow("Hand Skeleton Only (No Person)", display_img)

            # 按 'q' 退出
            if cv2.waitKey(1) & 0xFF == ord('q'):
                break

        cap.release()
        cv2.destroyAllWindows()


if __name__ == "__main__":
    controller = HandController()
    controller.start()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值