【深度学习实战—12】:基于MediaPipe的手势识别

在这里插入图片描述

✨博客主页:王乐予🎈
✨年轻人要:Living for the moment(活在当下)!💪
🏆推荐专栏:【图像处理】【千锤百炼Python】【深度学习】【排序算法】

目录

  • 😺一、MediaPipe概述
  • 😺二、MediaPipe手部特征点检测
  • 😺三、任务描述
  • 😺四、代码实现
    • 🐶4.1 度量函数
      • 🦄4.1.1 距离度量
      • 🦄4.1.2 角度度量
    • 🐶4.2 工作流程
    • 🐶4.3 代码实现
      • 🦄4.3.1 定义手指状态函数(弯曲 or 伸直)
      • 🦄4.3.2 定义 OK 手势判断函数
      • 🦄4.3.3 定义 Return 手势判断函数
      • 🦄4.3.4 定义 Left 手势判断函数
      • 🦄4.3.5 定义 Right 手势判断函数
      • 🦄4.3.6 定义 Like 手势判断函数
      • 🦄4.3.7 定义 Pause 手势判断函数
      • 🦄4.3.8 定义检测当前手势函数
    • 🐶4.4 完整代码
      • 🦄4.4.1 gesture_judgment.py
      • 🦄4.4.2 main.py

😺一、MediaPipe概述

MediaPipe 是一款由 Google Research 开发并开源的多媒体机器学习模型应用框架。

MediaPipe目前支持的解决方案(Solution)及支持的平台如下图所示:
在这里插入图片描述

😺二、MediaPipe手部特征点检测

官网描述:

https://ai.google.dev/edge/mediapipe/solutions/vision/hand_landmarker
The MediaPipe Hand Landmarker task lets you detect the landmarks of the hands in an image. You can use this task to locate key points of hands and render visual effects on them. This task operates on image data with a machine learning (ML) model as static data or a continuous stream and outputs hand landmarks in image coordinates, hand landmarks in world coordinates and handedness(left/right hand) of multiple detected hands.

该模型会跟踪手部 21 个关键点位置:
在这里插入图片描述

😺三、任务描述

本文将通过 Mediapipe 检测出手部关键点,并通过对各种关键点的位置判别,以达到手势识别的目的。本文将对如下 6 种手势进行判定识别:

  1. OK
  2. Return
  3. Left
  4. Right
  5. Like
  6. Pause

😺四、代码实现

🐶4.1 度量函数

🦄4.1.1 距离度量

计算两点之间的距离如下:

"""
计算两个点之间的距离:L2距离(欧式距离)
"""
def points_distance(x0, y0, x1, y1):
    return math.sqrt((x0 - x1) ** 2 + (y0 - y1) ** 2)

🦄4.1.2 角度度量

在这里插入图片描述

计算两向量之间的角度如下:

"""
计算两条线段之间的夹角,以弧度表示
"""
def compute_angle(x0, y0, x1, y1, x2, y2, x3, y3):
    AB = [x1 - x0, y1 - y0]
    CD = [x3 - x2, y3 - y2]

    dot_product = AB[0] * CD[0] + AB[1] * CD[1]

    AB_distance = points_distance(x0, y0, x1, y1) + 0.001   # 防止分母出现0
    CD_distance = points_distance(x2, y2, x3, y3) + 0.001

    cos_theta = dot_product / (AB_distance * CD_distance)

    theta = math.acos(cos_theta)

    return theta

🐶4.2 工作流程

  1. 通过 Mediapipe 获取所有手部关键点;
  2. 检测每根手指的状态(弯曲 or 伸直);
  3. 判断当前手势(定义多组手势判断函数);
  4. 如果连续30帧均为同一种手势,则可视化手势内容。

🐶4.3 代码实现

🦄4.3.1 定义手指状态函数(弯曲 or 伸直)

def detect_all_finger_state(all_points):

    finger_first_angle_bend_threshold = math.pi * 0.25  # 大拇指弯曲阈值
    finger_other_angle_bend_threshold = math.pi * 0.5  # 其他手指弯曲阈值
    finger_other_angle_straighten_threshold = math.pi * 0.2  # 其他手指伸直阈值

    first_is_bend = False
    first_is_straighten = False
    second_is_bend = False
    second_is_straighten = False
    third_is_bend = False
    third_is_straighten = False
    fourth_is_bend = False
    fourth_is_straighten = False
    fifth_is_bend = False
    fifth_is_straighten = False

    finger_first_angle = compute_angle(all_points['point0'][0], all_points['point0'][1], all_points['point1'][0], all_points['point1'][1],
                                        all_points['point2'][0], all_points['point2'][1], all_points['point4'][0], all_points['point4'][1])
    finger_sencond_angle = compute_angle(all_points['point0'][0], all_points['point0'][1], all_points['point5'][0], all_points['point5'][1],
                                        all_points['point6'][0], all_points['point6'][1], all_points['point8'][0], all_points['point8'][1])
    finger_third_angle = compute_angle(all_points['point0'][0], all_points['point0'][1], all_points['point9'][0], all_points['point9'][1],
                                        all_points['point10'][0], all_points['point10'][1], all_points['point12'][0], all_points['point12'][1])
    finger_fourth_angle = compute_angle(all_points['point0'][0], all_points['point0'][1], all_points['point13'][0], all_points['point13'][1],
                                        all_points['point14'][0], all_points['point14'][1], all_points['point16'][0], all_points['point16'][1])
    finger_fifth_angle = compute_angle(all_points['point0'][0], all_points['point0'][1], all_points['point17'][0], all_points['point17'][1],
                                        all_points['point18'][0], all_points['point18'][1], all_points['point20'][0], all_points['point20'][1])

    if finger_first_angle > finger_first_angle_bend_threshold:              # 判断大拇指是否弯曲
        first_is_bend = True
        first_is_straighten = False
    else:
        first_is_bend = False
        first_is_straighten = True

    if finger_sencond_angle > finger_other_angle_bend_threshold:            # 判断食指是否弯曲
        second_is_bend = True
    elif finger_sencond_angle < finger_other_angle_straighten_threshold:
        second_is_straighten = True
    else:
        second_is_bend = False
        second_is_straighten = False

    if finger_third_angle > finger_other_angle_bend_threshold:              # 判断中指是否弯曲
        third_is_bend = True
    elif finger_third_angle < finger_other_angle_straighten_threshold:
        third_is_straighten = True
    else:
        third_is_bend = False
        third_is_straighten = False

    if finger_fourth_angle > finger_other_angle_bend_threshold:             # 判断无名指是否弯曲
        fourth_is_bend = True
    elif finger_fourth_angle < finger_other_angle_straighten_threshold:
        fourth_is_straighten = True
    else:
        fourth_is_bend = False
        fourth_is_straighten = False

    if finger_fifth_angle > finger_other_angle_bend_threshold:              # 判断小拇指是否弯曲
        fifth_is_bend = True
    elif finger_fifth_angle < finger_other_angle_straighten_threshold:
        fifth_is_straighten = True
    else:
        fifth_is_bend = False
        fifth_is_straighten = False

    # 将手指的弯曲或伸直状态存在字典中,简化后续函数的参数
    bend_states = {'first': first_is_bend, 'second': second_is_bend, 'third': third_is_bend, 'fourth': fourth_is_bend, 'fifth': fifth_is_bend}
    straighten_states = {'first': first_is_straighten, 'second': second_is_straighten, 'third': third_is_straighten, 'fourth': fourth_is_straighten, 'fifth': fifth_is_straighten}

    return bend_states, straighten_states

🦄4.3.2 定义 OK 手势判断函数

OK 手势判断流程如图:
在这里插入图片描述

def judge_OK(all_points, bend_states, straighten_states):

    angle5_6_and_6_8 = compute_angle(all_points['point5'][0], all_points['point5'][1], all_points['point6'][0], all_points['point6'][1],
                                    all_points['point6'][0], all_points['point6'][1], all_points['point8'][0], all_points['point8'][1])

    if angle5_6_and_6_8 > 0.1 * math.pi and straighten_states['third'] and straighten_states['fourth'] and straighten_states['fifth']:

        distance4_and_8 = points_distance(all_points['point4'][0], all_points['point4'][1], all_points['point8'][0], all_points['point8'][1])
        distance2_and_6 = points_distance(all_points['point2'][0], all_points['point2'][1], all_points['point6'][0], all_points['point6'][1])
        distance4_and_6 = points_distance(all_points['point4'][0], all_points['point4'][1], all_points['point6'][0], all_points['point6'][1])

        if distance4_and_8 < distance2_and_6 and distance4_and_6 > distance4_and_8 and all_points['point11'][1] < all_points['point10'][1]:
            return 'OK'
        else:
            return False
    else:
        return False

🦄4.3.3 定义 Return 手势判断函数

Return 手势判断流程如图:
在这里插入图片描述

def judge_Return(all_points, bend_states, straighten_states):

    angle18_6_and_18_18_ = compute_angle(all_points['point18'][0], all_points['point18'][1], all_points['point6'][0], all_points['point6'][1],
                                        all_points['point18'][0], all_points['point18'][1], all_points['point18'][0] + 10, all_points['point18'][1])
    angle_6_18_and_6_6_ = compute_angle(all_points['point6'][0], all_points['point6'][1], all_points['point18'][0], all_points['point18'][1],
                                        all_points['point6'][0], all_points['point6'][1], all_points['point6'][0] + 10, all_points['point6'][1])
    angle_0_2_and_0_17 = compute_angle(all_points['point0'][0], all_points['point0'][1], all_points['point2'][0], all_points['point2'][1],
                                        all_points['point0'][0], all_points['point0'][1], all_points['point17'][0], all_points['point17'][1])

    if (bend_states['first'] and bend_states['second'] and bend_states['third'] and bend_states['fourth'] and bend_states['fifth'] and
            angle_0_2_and_0_17 > 0.15 * math.pi and
            all_points['point7'][1] > all_points['point6'][1] and all_points['point11'][1] > all_points['point10'][1] and
            all_points['point15'][1] > all_points['point14'][1] and all_points['point19'][1] > all_points['point18'][1]):

        if angle18_6_and_18_18_ < 0.1 * math.pi or angle_6_18_and_6_6_ < 0.1 * math.pi:
            return 'Return'
        else:
            return False
    else:
        return False

🦄4.3.4 定义 Left 手势判断函数

Left 手势判断流程如图:
在这里插入图片描述

def judge_Left(all_points, bend_states, straighten_states):

    angle5_6_and_6_8 = compute_angle(all_points['point5'][0], all_points['point5'][1], all_points['point6'][0], all_points['point6'][1],
                                    all_points['point6'][0], all_points['point6'][1], all_points['point8'][0], all_points['point8'][1])
    angle9_10_and_10_12 = compute_angle(all_points['point9'][0], all_points['point9'][1], all_points['point10'][0], all_points['point10'][1],
                                        all_points['point10'][0], all_points['point10'][1], all_points['point12'][0], all_points['point12'][1])
    angle13_14_and_14_16 = compute_angle(all_points['point13'][0], all_points['point13'][1], all_points['point14'][0], all_points['point14'][1],
                                        all_points['point14'][0], all_points['point14'][1], all_points['point16'][0], all_points['point16'][1])
    angle17_18_and_18_20 = compute_angle(all_points['point17'][0], all_points['point17'][1], all_points['point18'][0], all_points['point18'][1],
                                        all_points['point18'][0], all_points['point18'][1], all_points['point20'][0], all_points['point20'][1])
    angle0_6_and_0_4 = compute_angle(all_points['point0'][0], all_points['point0'][1], all_points['point6'][0], all_points['point6'][1],
                                    all_points['point0'][0], all_points['point0'][1], all_points['point4'][0], all_points['point4'][1])
    angle0_5_and_0_17 = compute_angle(all_points['point0'][0], all_points['point0'][1], all_points['point5'][0], all_points['point5'][1],
                                    all_points['point0'][0], all_points['point0'][1], all_points['point17'][0], all_points['point17'][1])

    if ((straighten_states['first'] and bend_states['second'] and bend_states['third'] and bend_states['fourth'] and bend_states['fifth']) or
        (straighten_states['first'] and angle5_6_and_6_8 > 0.2 * math.pi and angle9_10_and_10_12 > 0.2 * math.pi and
        angle13_14_and_14_16 > 0.2 * math.pi and angle17_18_and_18_20 > 0.2 * math.pi)):

        angle0_0__and_0_4 = compute_angle(all_points['point0'][0], all_points['point0'][1], all_points['point0'][0] + 10, all_points['point0'][1],
                                    all_points['point0'][0], all_points['point0'][1], all_points['point4'][0], all_points['point4'][1])

        if (angle0_5_and_0_17 > 0.15 * math.pi and angle0_0__and_0_4 > 0.7 * math.pi and all_points['point3'][0] < all_points['point2'][0] and
            angle0_6_and_0_4 > 0.1 * math.pi and all_points['point11'][1] > all_points['point10'][1] and all_points['point7'][1] > all_points['point6'][1] and
            all_points['point15'][1] > all_points['point14'][1] and all_points['point19'][1] > all_points['point18'][1]):
            return 'Left'
        else:
            return False
    else:
        return False

🦄4.3.5 定义 Right 手势判断函数

Right 手势判断流程如图:
在这里插入图片描述

def judge_Right(all_points, bend_states, straighten_states):

    angle0_5_and_0_17 = compute_angle(all_points['point0'][0], all_points['point0'][1], all_points['point5'][0], all_points['point5'][1],
                                    all_points['point0'][0], all_points['point0'][1], all_points['point17'][0], all_points['point17'][1])
    angle5_6_and_6_8 = compute_angle(all_points['point5'][0], all_points['point5'][1], all_points['point6'][0], all_points['point6'][1],
                                    all_points['point6'][0], all_points['point6'][1], all_points['point8'][0], all_points['point8'][1])
    angle9_10_and_10_12 = compute_angle(all_points['point9'][0], all_points['point9'][1], all_points['point10'][0], all_points['point10'][1],
                                        all_points['point10'][0], all_points['point10'][1], all_points['point12'][0], all_points['point12'][1])
    angle13_14_and_14_16 = compute_angle(all_points['point13'][0], all_points['point13'][1], all_points['point14'][0], all_points['point14'][1],
                                        all_points['point14'][0], all_points['point14'][1], all_points['point16'][0], all_points['point16'][1])
    angle17_18_and_18_20 = compute_angle(all_points['point17'][0], all_points['point17'][1], all_points['point18'][0], all_points['point18'][1],
                                        all_points['point18'][0], all_points['point18'][1], all_points['point20'][0], all_points['point20'][1])
    angle0_6_and_0_4 = compute_angle(all_points['point0'][0], all_points['point0'][1], all_points['point6'][0], all_points['point6'][1],
                                    all_points['point0'][0], all_points['point0'][1], all_points['point4'][0], all_points['point4'][1])

    if ((straighten_states['first'] and bend_states['second'] and bend_states['third'] and bend_states['fourth'] and bend_states['fifth']) or
        (straighten_states['first'] and angle5_6_and_6_8 > 0.2 * math.pi and angle9_10_and_10_12 > 0.2 * math.pi and
        angle13_14_and_14_16 > 0.2 * math.pi and angle17_18_and_18_20 > 0.2 * math.pi)):

        angle0_0__and_0_4 = compute_angle(all_points['point0'][0], all_points['point0'][1], all_points['point0'][0] + 10, all_points['point0'][1],
                                        all_points['point0'][0], all_points['point0'][1], all_points['point4'][0], all_points['point4'][1])

        if (angle0_5_and_0_17 > 0.15 * math.pi and angle0_0__and_0_4 < 0.25 * math.pi and all_points['point3'][0] > all_points['point2'][0] and
            angle0_6_and_0_4 > 0.1 * math.pi and all_points['point11'][1] > all_points['point10'][1] and all_points['point7'][1] > all_points['point6'][1] and
            all_points['point15'][1] > all_points['point14'][1] and all_points['point19'][1] > all_points['point18'][1]):
            return 'Right'
        else:
            return False
    else:
        return False

🦄4.3.6 定义 Like 手势判断函数

Like 手势判断流程如图:
在这里插入图片描述

def judge_Like(all_points, bend_states, straighten_states):

    angle2_4_and_2_8 = compute_angle(all_points['point2'][0], all_points['point2'][1], all_points['point4'][0], all_points['point4'][1],
                                    all_points['point2'][0], all_points['point2'][1], all_points['point8'][0], all_points['point8'][1])
    angle2_3_and_3_4 = compute_angle(all_points['point2'][0], all_points['point2'][1], all_points['point3'][0], all_points['point3'][1],
                                    all_points['point3'][0], all_points['point3'][1], all_points['point4'][0], all_points['point4'][1])
    angle5_6_and_6_8 = compute_angle(all_points['point5'][0], all_points['point5'][1], all_points['point6'][0], all_points['point6'][1],
                                    all_points['point6'][0], all_points['point6'][1], all_points['point8'][0], all_points['point8'][1])
    angle9_10_and_10_12 = compute_angle(all_points['point9'][0], all_points['point9'][1], all_points['point10'][0], all_points['point10'][1],
                                        all_points['point10'][0], all_points['point10'][1], all_points['point12'][0], all_points['point12'][1])
    angle13_14_and_14_16 = compute_angle(all_points['point13'][0], all_points['point13'][1], all_points['point14'][0], all_points['point14'][1],
                                        all_points['point14'][0], all_points['point14'][1], all_points['point16'][0], all_points['point16'][1])
    angle17_18_and_18_20 = compute_angle(all_points['point17'][0], all_points['point17'][1], all_points['point18'][0], all_points['point18'][1],
                                        all_points['point18'][0], all_points['point18'][1], all_points['point20'][0], all_points['point20'][1])
    angle0_6_and_0_4 = compute_angle(all_points['point0'][0], all_points['point0'][1], all_points['point6'][0], all_points['point6'][1],
                                    all_points['point0'][0], all_points['point0'][1], all_points['point4'][0], all_points['point4'][1])

    if (angle2_3_and_3_4 < 0.2 * math.pi and bend_states['second'] and bend_states['third'] and bend_states['fourth'] and bend_states['fifth']) or (angle2_3_and_3_4 < 0.2 * math.pi and angle5_6_and_6_8 > 0.2 * math.pi and angle9_10_and_10_12 > 0.2 * math.pi and angle13_14_and_14_16 > 0.2 * math.pi and angle17_18_and_18_20 > 0.2 * math.pi):

        angle0_0__and_0_4 = compute_angle(all_points['point0'][0], all_points['point0'][1], all_points['point0'][0] + 10, all_points['point0'][1],
                                        all_points['point0'][0], all_points['point0'][1], all_points['point4'][0], all_points['point4'][1])

        if angle0_0__and_0_4 > 0.25 * math.pi and angle0_0__and_0_4 < 0.75 * math.pi and all_points['point3'][1] > all_points['point4'][1] and all_points['point5'][1] < all_points['point9'][1] and all_points['point9'][1] < all_points['point13'][1] and all_points['point13'][1] < all_points['point17'][1] and all_points['point2'][1] < all_points['point5'][1] and angle0_6_and_0_4 > 0.1 * math.pi and angle2_4_and_2_8 > 0.1 * math.pi:
            return 'Like'
        else:
            return False
    else:
        return False

🦄4.3.7 定义 Pause 手势判断函数

Pause 手势判断流程如图:
在这里插入图片描述

def judge_Pause(all_points, bend_states, straighten_states):

    angle0_5_and_0_17 = compute_angle(all_points['point0'][0], all_points['point0'][1], all_points['point5'][0], all_points['point5'][1],
                                    all_points['point0'][0], all_points['point0'][1], all_points['point17'][0], all_points['point17'][1])
    angle2_3_and_2_4 = compute_angle(all_points['point2'][0], all_points['point2'][1], all_points['point3'][0], all_points['point3'][1],
                                    all_points['point2'][0], all_points['point2'][1], all_points['point4'][0], all_points['point4'][1])
    angle5_6_and_6_8 = compute_angle(all_points['point5'][0], all_points['point5'][1], all_points['point6'][0], all_points['point6'][1],
                                    all_points['point6'][0], all_points['point6'][1], all_points['point8'][0], all_points['point8'][1])
    angle9_10_and_10_12 = compute_angle(all_points['point9'][0], all_points['point9'][1], all_points['point10'][0], all_points['point10'][1],
                                        all_points['point10'][0], all_points['point10'][1], all_points['point12'][0], all_points['point12'][1])
    angle13_14_and_14_16 = compute_angle(all_points['point13'][0], all_points['point13'][1], all_points['point14'][0], all_points['point14'][1],
                                        all_points['point14'][0], all_points['point14'][1], all_points['point16'][0], all_points['point16'][1])
    angle17_18_and_18_20 = compute_angle(all_points['point17'][0], all_points['point17'][1], all_points['point18'][0], all_points['point18'][1],
                                        all_points['point18'][0], all_points['point18'][1], all_points['point20'][0], all_points['point20'][1])
    angle1_2_and_2_4 = compute_angle(all_points['point1'][0], all_points['point1'][1], all_points['point2'][0], all_points['point2'][1],
                                    all_points['point2'][0], all_points['point2'][1], all_points['point4'][0], all_points['point4'][1])

    if angle2_3_and_2_4 < 0.2 * math.pi and angle5_6_and_6_8 < 0.07 * math.pi and angle9_10_and_10_12 < 0.07 * math.pi and angle13_14_and_14_16 < 0.07 * math.pi and angle17_18_and_18_20 < 0.07 * math.pi and angle9_10_and_10_12 < 0.07 * math.pi and angle1_2_and_2_4 < 0.25 * math.pi:
        if angle0_5_and_0_17 > 0.1 * math.pi and all_points['point3'][1] > all_points['point4'][1] and all_points['point6'][1] > all_points['point8'][1] and all_points['point10'][1] > all_points['point12'][1]:
            return 'Pause'
        else:
            return False
    else:
        return False

🦄4.3.8 定义检测当前手势函数

"""
检测当前手势,返回当前手势
"""
def detect_hand_state(all_points, bend_states, straighten_states):
    state_OK = judge_OK(all_points, bend_states, straighten_states)
    state_Return = judge_Return(all_points, bend_states, straighten_states)
    state_Left = judge_Left(all_points, bend_states, straighten_states)
    state_Right = judge_Right(all_points, bend_states, straighten_states)
    state_Like = judge_Like(all_points, bend_states, straighten_states)
    state_Pause = judge_Pause(all_points, bend_states, straighten_states)

    if state_OK == 'OK':
        return 'OK'
    elif state_Return == 'Return':
        return 'Return'
    elif state_Left == 'Left':
        return 'Left'
    elif state_Right == 'Right':
        return 'Right'
    elif state_Like == 'Like':
        return 'Like'
    elif state_Pause == 'Pause':
        return 'Pause'
    else:
        return 'None'

🐶4.4 完整代码

🦄4.4.1 gesture_judgment.py

import math


"""
计算两个点之间的距离:L2距离(欧式距离)
"""
def points_distance(x0, y0, x1, y1):
    return math.sqrt((x0 - x1) ** 2 + (y0 - y1) ** 2)


"""
计算两条线段之间的夹角,以弧度表示
"""
def compute_angle(x0, y0, x1, y1, x2, y2, x3, y3):
    AB = [x1 - x0, y1 - y0]
    CD = [x3 - x2, y3 - y2]

    dot_product = AB[0] * CD[0] + AB[1] * CD[1]

    AB_distance = points_distance(x0, y0, x1, y1) + 0.001   # 防止分母出现0
    CD_distance = points_distance(x2, y2, x3, y3) + 0.001

    cos_theta = dot_product / (AB_distance * CD_distance)

    theta = math.acos(cos_theta)

    return theta


"""
检测所有手指状态(判断每根手指弯曲 or 伸直)
大拇指只有弯曲和伸直两种状态,其他手指除了弯曲和伸直还包含第三种状态(手指没有伸直,但是也没有达到弯曲的标准),第三种状态是为了后续更新迭代用的,这里用不到
"""
def detect_all_finger_state(all_points):

    finger_first_angle_bend_threshold = math.pi * 0.25  # 大拇指弯曲阈值
    finger_other_angle_bend_threshold = math.pi * 0.5  # 其他手指弯曲阈值
    finger_other_angle_straighten_threshold = math.pi * 0.2  # 其他手指伸直阈值

    first_is_bend = False
    first_is_straighten = False
    second_is_bend = False
    second_is_straighten = False
    third_is_bend = False
    third_is_straighten = False
    fourth_is_bend = False
    fourth_is_straighten = False
    fifth_is_bend = False
    fifth_is_straighten = False

    finger_first_angle = compute_angle(all_points['point0'][0], all_points['point0'][1], all_points['point1'][0], all_points['point1'][1],
                                        all_points['point2'][0], all_points['point2'][1], all_points['point4'][0], all_points['point4'][1])
    finger_sencond_angle = compute_angle(all_points['point0'][0], all_points['point0'][1], all_points['point5'][0], all_points['point5'][1],
                                        all_points['point6'][0], all_points['point6'][1], all_points['point8'][0], all_points['point8'][1])
    finger_third_angle = compute_angle(all_points['point0'][0], all_points['point0'][1], all_points['point9'][0], all_points['point9'][1],
                                        all_points['point10'][0], all_points['point10'][1], all_points['point12'][0], all_points['point12'][1])
    finger_fourth_angle = compute_angle(all_points['point0'][0], all_points['point0'][1], all_points['point13'][0], all_points['point13'][1],
                                        all_points['point14'][0], all_points['point14'][1], all_points['point16'][0], all_points['point16'][1])
    finger_fifth_angle = compute_angle(all_points['point0'][0], all_points['point0'][1], all_points['point17'][0], all_points['point17'][1],
                                        all_points['point18'][0], all_points['point18'][1], all_points['point20'][0], all_points['point20'][1])

    if finger_first_angle > finger_first_angle_bend_threshold:              # 判断大拇指是否弯曲
        first_is_bend = True
        first_is_straighten = False
    else:
        first_is_bend = False
        first_is_straighten = True

    if finger_sencond_angle > finger_other_angle_bend_threshold:            # 判断食指是否弯曲
        second_is_bend = True
    elif finger_sencond_angle < finger_other_angle_straighten_threshold:
        second_is_straighten = True
    else:
        second_is_bend = False
        second_is_straighten = False

    if finger_third_angle > finger_other_angle_bend_threshold:              # 判断中指是否弯曲
        third_is_bend = True
    elif finger_third_angle < finger_other_angle_straighten_threshold:
        third_is_straighten = True
    else:
        third_is_bend = False
        third_is_straighten = False

    if finger_fourth_angle > finger_other_angle_bend_threshold:             # 判断无名指是否弯曲
        fourth_is_bend = True
    elif finger_fourth_angle < finger_other_angle_straighten_threshold:
        fourth_is_straighten = True
    else:
        fourth_is_bend = False
        fourth_is_straighten = False

    if finger_fifth_angle > finger_other_angle_bend_threshold:              # 判断小拇指是否弯曲
        fifth_is_bend = True
    elif finger_fifth_angle < finger_other_angle_straighten_threshold:
        fifth_is_straighten = True
    else:
        fifth_is_bend = False
        fifth_is_straighten = False

    # 将手指的弯曲或伸直状态存在字典中,简化后续函数的参数
    bend_states = {'first': first_is_bend, 'second': second_is_bend, 'third': third_is_bend, 'fourth': fourth_is_bend, 'fifth': fifth_is_bend}
    straighten_states = {'first': first_is_straighten, 'second': second_is_straighten, 'third': third_is_straighten, 'fourth': fourth_is_straighten, 'fifth': fifth_is_straighten}

    return bend_states, straighten_states


"""
判断是否为 OK 手势
"""
def judge_OK(all_points, bend_states, straighten_states):

    angle5_6_and_6_8 = compute_angle(all_points['point5'][0], all_points['point5'][1], all_points['point6'][0], all_points['point6'][1],
                                    all_points['point6'][0], all_points['point6'][1], all_points['point8'][0], all_points['point8'][1])

    if angle5_6_and_6_8 > 0.1 * math.pi and straighten_states['third'] and straighten_states['fourth'] and straighten_states['fifth']:

        distance4_and_8 = points_distance(all_points['point4'][0], all_points['point4'][1], all_points['point8'][0], all_points['point8'][1])
        distance2_and_6 = points_distance(all_points['point2'][0], all_points['point2'][1], all_points['point6'][0], all_points['point6'][1])
        distance4_and_6 = points_distance(all_points['point4'][0], all_points['point4'][1], all_points['point6'][0], all_points['point6'][1])

        if distance4_and_8 < distance2_and_6 and distance4_and_6 > distance4_and_8 and all_points['point11'][1] < all_points['point10'][1]:
            return 'OK'
        else:
            return False
    else:
        return False


"""
判断是否为 Return 手势
"""
def judge_Return(all_points, bend_states, straighten_states):

    angle18_6_and_18_18_ = compute_angle(all_points['point18'][0], all_points['point18'][1], all_points['point6'][0], all_points['point6'][1],
                                        all_points['point18'][0], all_points['point18'][1], all_points['point18'][0] + 10, all_points['point18'][1])
    angle_6_18_and_6_6_ = compute_angle(all_points['point6'][0], all_points['point6'][1], all_points['point18'][0], all_points['point18'][1],
                                        all_points['point6'][0], all_points['point6'][1], all_points['point6'][0] + 10, all_points['point6'][1])
    angle_0_2_and_0_17 = compute_angle(all_points['point0'][0], all_points['point0'][1], all_points['point2'][0], all_points['point2'][1],
                                        all_points['point0'][0], all_points['point0'][1], all_points['point17'][0], all_points['point17'][1])

    if (bend_states['first'] and bend_states['second'] and bend_states['third'] and bend_states['fourth'] and bend_states['fifth'] and
            angle_0_2_and_0_17 > 0.15 * math.pi and
            all_points['point7'][1] > all_points['point6'][1] and all_points['point11'][1] > all_points['point10'][1] and
            all_points['point15'][1] > all_points['point14'][1] and all_points['point19'][1] > all_points['point18'][1]):

        if angle18_6_and_18_18_ < 0.1 * math.pi or angle_6_18_and_6_6_ < 0.1 * math.pi:
            return 'Return'
        else:
            return False
    else:
        return False


"""
判断是否为 Left 手势
"""
def judge_Left(all_points, bend_states, straighten_states):

    angle5_6_and_6_8 = compute_angle(all_points['point5'][0], all_points['point5'][1], all_points['point6'][0], all_points['point6'][1],
                                    all_points['point6'][0], all_points['point6'][1], all_points['point8'][0], all_points['point8'][1])
    angle9_10_and_10_12 = compute_angle(all_points['point9'][0], all_points['point9'][1], all_points['point10'][0], all_points['point10'][1],
                                        all_points['point10'][0], all_points['point10'][1], all_points['point12'][0], all_points['point12'][1])
    angle13_14_and_14_16 = compute_angle(all_points['point13'][0], all_points['point13'][1], all_points['point14'][0], all_points['point14'][1],
                                        all_points['point14'][0], all_points['point14'][1], all_points['point16'][0], all_points['point16'][1])
    angle17_18_and_18_20 = compute_angle(all_points['point17'][0], all_points['point17'][1], all_points['point18'][0], all_points['point18'][1],
                                        all_points['point18'][0], all_points['point18'][1], all_points['point20'][0], all_points['point20'][1])
    angle0_6_and_0_4 = compute_angle(all_points['point0'][0], all_points['point0'][1], all_points['point6'][0], all_points['point6'][1],
                                    all_points['point0'][0], all_points['point0'][1], all_points['point4'][0], all_points['point4'][1])
    angle0_5_and_0_17 = compute_angle(all_points['point0'][0], all_points['point0'][1], all_points['point5'][0], all_points['point5'][1],
                                    all_points['point0'][0], all_points['point0'][1], all_points['point17'][0], all_points['point17'][1])

    if ((straighten_states['first'] and bend_states['second'] and bend_states['third'] and bend_states['fourth'] and bend_states['fifth']) or
        (straighten_states['first'] and angle5_6_and_6_8 > 0.2 * math.pi and angle9_10_and_10_12 > 0.2 * math.pi and
        angle13_14_and_14_16 > 0.2 * math.pi and angle17_18_and_18_20 > 0.2 * math.pi)):

        angle0_0__and_0_4 = compute_angle(all_points['point0'][0], all_points['point0'][1], all_points['point0'][0] + 10, all_points['point0'][1],
                                    all_points['point0'][0], all_points['point0'][1], all_points['point4'][0], all_points['point4'][1])

        if (angle0_5_and_0_17 > 0.15 * math.pi and angle0_0__and_0_4 > 0.7 * math.pi and all_points['point3'][0] < all_points['point2'][0] and
            angle0_6_and_0_4 > 0.1 * math.pi and all_points['point11'][1] > all_points['point10'][1] and all_points['point7'][1] > all_points['point6'][1] and
            all_points['point15'][1] > all_points['point14'][1] and all_points['point19'][1] > all_points['point18'][1]):
            return 'Left'
        else:
            return False
    else:
        return False


"""
判断是否为 Right 手势
"""
def judge_Right(all_points, bend_states, straighten_states):

    angle0_5_and_0_17 = compute_angle(all_points['point0'][0], all_points['point0'][1], all_points['point5'][0], all_points['point5'][1],
                                    all_points['point0'][0], all_points['point0'][1], all_points['point17'][0], all_points['point17'][1])
    angle5_6_and_6_8 = compute_angle(all_points['point5'][0], all_points['point5'][1], all_points['point6'][0], all_points['point6'][1],
                                    all_points['point6'][0], all_points['point6'][1], all_points['point8'][0], all_points['point8'][1])
    angle9_10_and_10_12 = compute_angle(all_points['point9'][0], all_points['point9'][1], all_points['point10'][0], all_points['point10'][1],
                                        all_points['point10'][0], all_points['point10'][1], all_points['point12'][0], all_points['point12'][1])
    angle13_14_and_14_16 = compute_angle(all_points['point13'][0], all_points['point13'][1], all_points['point14'][0], all_points['point14'][1],
                                        all_points['point14'][0], all_points['point14'][1], all_points['point16'][0], all_points['point16'][1])
    angle17_18_and_18_20 = compute_angle(all_points['point17'][0], all_points['point17'][1], all_points['point18'][0], all_points['point18'][1],
                                        all_points['point18'][0], all_points['point18'][1], all_points['point20'][0], all_points['point20'][1])
    angle0_6_and_0_4 = compute_angle(all_points['point0'][0], all_points['point0'][1], all_points['point6'][0], all_points['point6'][1],
                                    all_points['point0'][0], all_points['point0'][1], all_points['point4'][0], all_points['point4'][1])

    if ((straighten_states['first'] and bend_states['second'] and bend_states['third'] and bend_states['fourth'] and bend_states['fifth']) or
        (straighten_states['first'] and angle5_6_and_6_8 > 0.2 * math.pi and angle9_10_and_10_12 > 0.2 * math.pi and
        angle13_14_and_14_16 > 0.2 * math.pi and angle17_18_and_18_20 > 0.2 * math.pi)):

        angle0_0__and_0_4 = compute_angle(all_points['point0'][0], all_points['point0'][1], all_points['point0'][0] + 10, all_points['point0'][1],
                                        all_points['point0'][0], all_points['point0'][1], all_points['point4'][0], all_points['point4'][1])

        if (angle0_5_and_0_17 > 0.15 * math.pi and angle0_0__and_0_4 < 0.25 * math.pi and all_points['point3'][0] > all_points['point2'][0] and
            angle0_6_and_0_4 > 0.1 * math.pi and all_points['point11'][1] > all_points['point10'][1] and all_points['point7'][1] > all_points['point6'][1] and
            all_points['point15'][1] > all_points['point14'][1] and all_points['point19'][1] > all_points['point18'][1]):
            return 'Right'
        else:
            return False
    else:
        return False


"""
判断是否为 Like 手势
"""
def judge_Like(all_points, bend_states, straighten_states):

    angle2_4_and_2_8 = compute_angle(all_points['point2'][0], all_points['point2'][1], all_points['point4'][0], all_points['point4'][1],
                                    all_points['point2'][0], all_points['point2'][1], all_points['point8'][0], all_points['point8'][1])
    angle2_3_and_3_4 = compute_angle(all_points['point2'][0], all_points['point2'][1], all_points['point3'][0], all_points['point3'][1],
                                    all_points['point3'][0], all_points['point3'][1], all_points['point4'][0], all_points['point4'][1])
    angle5_6_and_6_8 = compute_angle(all_points['point5'][0], all_points['point5'][1], all_points['point6'][0], all_points['point6'][1],
                                    all_points['point6'][0], all_points['point6'][1], all_points['point8'][0], all_points['point8'][1])
    angle9_10_and_10_12 = compute_angle(all_points['point9'][0], all_points['point9'][1], all_points['point10'][0], all_points['point10'][1],
                                        all_points['point10'][0], all_points['point10'][1], all_points['point12'][0], all_points['point12'][1])
    angle13_14_and_14_16 = compute_angle(all_points['point13'][0], all_points['point13'][1], all_points['point14'][0], all_points['point14'][1],
                                        all_points['point14'][0], all_points['point14'][1], all_points['point16'][0], all_points['point16'][1])
    angle17_18_and_18_20 = compute_angle(all_points['point17'][0], all_points['point17'][1], all_points['point18'][0], all_points['point18'][1],
                                        all_points['point18'][0], all_points['point18'][1], all_points['point20'][0], all_points['point20'][1])
    angle0_6_and_0_4 = compute_angle(all_points['point0'][0], all_points['point0'][1], all_points['point6'][0], all_points['point6'][1],
                                    all_points['point0'][0], all_points['point0'][1], all_points['point4'][0], all_points['point4'][1])

    if (angle2_3_and_3_4 < 0.2 * math.pi and bend_states['second'] and bend_states['third'] and bend_states['fourth'] and bend_states['fifth']) or (angle2_3_and_3_4 < 0.2 * math.pi and angle5_6_and_6_8 > 0.2 * math.pi and angle9_10_and_10_12 > 0.2 * math.pi and angle13_14_and_14_16 > 0.2 * math.pi and angle17_18_and_18_20 > 0.2 * math.pi):

        angle0_0__and_0_4 = compute_angle(all_points['point0'][0], all_points['point0'][1], all_points['point0'][0] + 10, all_points['point0'][1],
                                        all_points['point0'][0], all_points['point0'][1], all_points['point4'][0], all_points['point4'][1])

        if angle0_0__and_0_4 > 0.25 * math.pi and angle0_0__and_0_4 < 0.75 * math.pi and all_points['point3'][1] > all_points['point4'][1] and all_points['point5'][1] < all_points['point9'][1] and all_points['point9'][1] < all_points['point13'][1] and all_points['point13'][1] < all_points['point17'][1] and all_points['point2'][1] < all_points['point5'][1] and angle0_6_and_0_4 > 0.1 * math.pi and angle2_4_and_2_8 > 0.1 * math.pi:
            return 'Like'
        else:
            return False
    else:
        return False


"""
判断是否为 Pause 手势
"""
def judge_Pause(all_points, bend_states, straighten_states):

    angle0_5_and_0_17 = compute_angle(all_points['point0'][0], all_points['point0'][1], all_points['point5'][0], all_points['point5'][1],
                                    all_points['point0'][0], all_points['point0'][1], all_points['point17'][0], all_points['point17'][1])
    angle2_3_and_2_4 = compute_angle(all_points['point2'][0], all_points['point2'][1], all_points['point3'][0], all_points['point3'][1],
                                    all_points['point2'][0], all_points['point2'][1], all_points['point4'][0], all_points['point4'][1])
    angle5_6_and_6_8 = compute_angle(all_points['point5'][0], all_points['point5'][1], all_points['point6'][0], all_points['point6'][1],
                                    all_points['point6'][0], all_points['point6'][1], all_points['point8'][0], all_points['point8'][1])
    angle9_10_and_10_12 = compute_angle(all_points['point9'][0], all_points['point9'][1], all_points['point10'][0], all_points['point10'][1],
                                        all_points['point10'][0], all_points['point10'][1], all_points['point12'][0], all_points['point12'][1])
    angle13_14_and_14_16 = compute_angle(all_points['point13'][0], all_points['point13'][1], all_points['point14'][0], all_points['point14'][1],
                                        all_points['point14'][0], all_points['point14'][1], all_points['point16'][0], all_points['point16'][1])
    angle17_18_and_18_20 = compute_angle(all_points['point17'][0], all_points['point17'][1], all_points['point18'][0], all_points['point18'][1],
                                        all_points['point18'][0], all_points['point18'][1], all_points['point20'][0], all_points['point20'][1])
    angle1_2_and_2_4 = compute_angle(all_points['point1'][0], all_points['point1'][1], all_points['point2'][0], all_points['point2'][1],
                                    all_points['point2'][0], all_points['point2'][1], all_points['point4'][0], all_points['point4'][1])

    if angle2_3_and_2_4 < 0.2 * math.pi and angle5_6_and_6_8 < 0.07 * math.pi and angle9_10_and_10_12 < 0.07 * math.pi and angle13_14_and_14_16 < 0.07 * math.pi and angle17_18_and_18_20 < 0.07 * math.pi and angle9_10_and_10_12 < 0.07 * math.pi and angle1_2_and_2_4 < 0.25 * math.pi:
        if angle0_5_and_0_17 > 0.1 * math.pi and all_points['point3'][1] > all_points['point4'][1] and all_points['point6'][1] > all_points['point8'][1] and all_points['point10'][1] > all_points['point12'][1]:
            return 'Pause'
        else:
            return False
    else:
        return False


"""
检测当前手势,返回当前手势
"""
def detect_hand_state(all_points, bend_states, straighten_states):
    state_OK = judge_OK(all_points, bend_states, straighten_states)
    state_Return = judge_Return(all_points, bend_states, straighten_states)
    state_Left = judge_Left(all_points, bend_states, straighten_states)
    state_Right = judge_Right(all_points, bend_states, straighten_states)
    state_Like = judge_Like(all_points, bend_states, straighten_states)
    state_Pause = judge_Pause(all_points, bend_states, straighten_states)

    if state_OK == 'OK':
        return 'OK'
    elif state_Return == 'Return':
        return 'Return'
    elif state_Left == 'Left':
        return 'Left'
    elif state_Right == 'Right':
        return 'Right'
    elif state_Like == 'Like':
        return 'Like'
    elif state_Pause == 'Pause':
        return 'Pause'
    else:
        return 'None'

🦄4.4.2 main.py

import cv2
import mediapipe as mp
import time
from gesture_judgment import detect_all_finger_state, detect_hand_state


mp_hands = mp.solutions.hands
hands = mp_hands.Hands(static_image_mode=False, max_num_hands=1, min_detection_confidence=0.5, min_tracking_confidence=0.5)
mp_drawing = mp.solutions.drawing_utils

recent_states = [''] * 30    # 存储最近 30 次的手势判断结果

cap = cv2.VideoCapture(0)

prev_time = 0
while True:
    ret, frame = cap.read()
    frame = cv2.flip(frame, 1)  # Horizontal mirror flipping
    h, w = frame.shape[:2]
    image = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
    keypoints = hands.process(image)

    if keypoints.multi_hand_landmarks:
        lm = keypoints.multi_hand_landmarks[0]
        lmHand = mp_hands.HandLandmark

        landmark_list = [[] for _ in range(6)]  # landmark_list有 6 个子列表,分别存储着根节点坐标(0点)以及其它 5 根手指的关键点坐标

        for index, landmark in enumerate(lm.landmark):
            x = int(landmark.x * w)
            y = int(landmark.y * h)
            if index == lmHand.WRIST:
                landmark_list[0].append((x, y))
            elif 1 <= index <= 4:
                landmark_list[1].append((x, y))
            elif 5 <= index <= 8:
                landmark_list[2].append((x, y))
            elif 9 <= index <= 12:
                landmark_list[3].append((x, y))
            elif 13 <= index <= 16:
                landmark_list[4].append((x, y))
            elif 17 <= index <= 20:
                landmark_list[5].append((x, y))

        # 获取所有关节点的坐标
        point0 = landmark_list[0][0]
        point1, point2, point3, point4 = landmark_list[1][0], landmark_list[1][1], landmark_list[1][2], landmark_list[1][3]
        point5, point6, point7, point8 = landmark_list[2][0], landmark_list[2][1], landmark_list[2][2], landmark_list[2][3]
        point9, point10, point11, point12 = landmark_list[3][0], landmark_list[3][1], landmark_list[3][2], landmark_list[3][3]
        point13, point14, point15, point16 = landmark_list[4][0], landmark_list[4][1], landmark_list[4][2], landmark_list[4][3]
        point17, point18, point19, point20 = landmark_list[5][0], landmark_list[5][1], landmark_list[5][2], landmark_list[5][3]

        # 将所有关键点的坐标存储到一起,简化后续函数的参数
        all_points = {'point0': landmark_list[0][0],
                        'point1': landmark_list[1][0], 'point2': landmark_list[1][1], 'point3': landmark_list[1][2], 'point4': landmark_list[1][3],
                        'point5': landmark_list[2][0], 'point6': landmark_list[2][1], 'point7': landmark_list[2][2], 'point8': landmark_list[2][3],
                        'point9': landmark_list[3][0], 'point10': landmark_list[3][1], 'point11': landmark_list[3][2], 'point12': landmark_list[3][3],
                        'point13': landmark_list[4][0], 'point14': landmark_list[4][1], 'point15': landmark_list[4][2], 'point16': landmark_list[4][3],
                        'point17': landmark_list[5][0], 'point18': landmark_list[5][1], 'point19': landmark_list[5][2], 'point20': landmark_list[5][3]}

        # 调用函数,判断每根手指的弯曲或伸直状态
        bend_states, straighten_states = detect_all_finger_state(all_points)

        # 调用函数,检测当前手势
        current_state = detect_hand_state(all_points, bend_states, straighten_states)

        # 更新最近状态列表
        recent_states.pop(0)
        recent_states.append(current_state)

        # 检查列表中的所有状态是否相同
        if len(set(recent_states)) == 1:        # 如果连续30帧的手势状态都相同,则认为手势稳定,输出当前手势
            print("Detected consistent hand state:", recent_states[0])
            cv2.putText(frame, current_state, (10, 70), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 2, cv2.LINE_AA)


        for hand_landmarks in keypoints.multi_hand_landmarks:       # keypoints.multi_hand_landmarks是一个列表,只有一个元素,存储着21个关键点的xyz坐标。使用for循环遍历
            mp_drawing.draw_landmarks(frame, hand_landmarks, mp_hands.HAND_CONNECTIONS,
                                    mp_drawing.DrawingSpec(color=(0, 255, 0), thickness=2, circle_radius=4),
                                    mp_drawing.DrawingSpec(color=(255, 0, 0), thickness=2, circle_radius=2))

    curr_time = time.time()             # 计算帧率
    fps = 1 / (curr_time - prev_time)
    prev_time = curr_time

    # 在画面上绘制帧率
    cv2.putText(frame, f"FPS: {int(fps)}", (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 255, 255), 2)

    cv2.imshow("Hand Detection", frame)
    if cv2.waitKey(1) == ord("q"):
        break

cap.release()
cv2.destroyAllWindows()

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/896248.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Java设计模式梳理:行为型模式(策略,观察者等)

行为型模式 行为型模式关注的是各个类之间的相互作用&#xff0c;将职责划分清楚&#xff0c;使得我们的代码更加地清晰。 策略模式 策略模式太常用了&#xff0c;所以把它放到最前面进行介绍。它比较简单&#xff0c;我就不废话&#xff0c;直接用代码说事吧。 下面设计的…

电能表预付费系统-标准传输规范(STS)(16)

6.3.9 MPL: MaximumPowerLimit&#xff08;最大功率限制&#xff09; The maximum power limit field is a 1 6-bit field that indicates the maximum power that the load may draw, in watts. Calculation of this field is identical to that of the TransferAmount field…

【JavaEE】——自定义协议方案、UDP协议

阿华代码&#xff0c;不是逆风&#xff0c;就是我疯 你们的点赞收藏是我前进最大的动力&#xff01;&#xff01; 希望本文内容能够帮助到你&#xff01;&#xff01; 目录 一&#xff1a;自定义协议 1&#xff1a;自定义协议 &#xff08;1&#xff09;交互哪些信息 &…

数据库设计与开发—初识SQLite与DbGate

一、SQLite与DbGate简介 &#xff08;一&#xff09;SQLite[1][3] SQLite 是一个部署最广泛、用 C 语言编写的数据库引擎&#xff0c;属于嵌入式数据库&#xff0c;其作为库被软件开发人员嵌入到应用程序中。 SQLite 的设计允许在不安装数据库管理系统或不需要数据库管理员的情…

C++中的继承(1)

1.继承的概念 继承(inheritance)机制是面向对象程序设计使代码可以复用的最重要的手段&#xff0c;它允许我们在保持原有类特性的基础上进行扩展&#xff0c;增加⽅法(成员函数)和属性(成员变量)&#xff0c;这样产生新的类&#xff0c;称派生类&#xff08;也被称为子类&…

Vue 3集成海康Web插件实现视频监控

​&#x1f308;个人主页&#xff1a;前端青山 &#x1f525;系列专栏&#xff1a;组件封装篇 &#x1f516;人终将被年少不可得之物困其一生 依旧青山,本期给大家带来组件封装篇专栏内容:Vue 3集成海康Web插件实现视频监控 引言 最近在项目中使用了 Vue 3 结合海康Web插件来实…

Django项目创建

安装 pip install django 创建项目 首先打开powershell打开项目与创建到的文件夹 django-admin startproject django_demo01 django-admin startproject 项目名 多出了一个django_demo01的文件夹&#xff0c;这就是我们的项目了 打开项目文件夹&#xff0c;发现一个文件和…

必读推荐:掌握大模型应用的精华书籍,非常详细收藏我这一篇就够了

在这个信息爆炸的时代&#xff0c;人工智能正以前所未有的速度和规模渗透到我们生活的方方面面。其中&#xff0c;大模型应用作为 AI 领域的一大亮点&#xff0c;不仅在学术界引起广泛关注&#xff0c;更在工业界展现出巨大的应用潜力。从自然语言处理到图像识别&#xff0c;从…

最新必应Bing开户条件、流程及注意事项介绍

有效的广告推广对于企业提升品牌影响力和市场占有率至关重要。微软旗下的必应Bing搜索引擎&#xff0c;作为全球知名的搜索平台之一&#xff0c;为企业提供了精准、高效的广告推广服务。那么&#xff0c;如何在必应上开设广告账户呢&#xff1f;下面将详细介绍必应广告开户的条…

springboot 整合 快手 移动应用 授权 发布视频 小黄车

前言&#xff1a; 因快手文档混乱&#xff0c;官方社区技术交流仍有很多未解之谜&#xff0c;下面3种文档的定义先区分。 代码中的JSON相关工具均用hutool工具包 1.快手 移动双端 原生SDK 文档https://mp.kuaishou.com/platformDocs/develop/mobile-app/ios.html 2.快手 Api 开…

探索光耦:光耦——不间断电源(UPS)系统中的安全高效卫士

在现代社会&#xff0c;不间断电源&#xff08;UPS&#xff09;系统已成为保障关键设备和数据安全的关键设施&#xff0c;广泛应用于企业数据中心、家庭电子设备等场景。UPS能在电力中断或波动时提供稳定电力&#xff0c;确保设备持续运行。而在这套系统中&#xff0c;光耦&…

深入理解AQS:并发编程中的利器及其在业务场景中的应用

1. 什么是AQS&#xff08;AbstractQueuedSynchronizer&#xff09;&#xff1f; AQS&#xff0c;全称为AbstractQueuedSynchronizer&#xff0c;是Java并发包中核心的基础框架&#xff0c;用于构建锁和同步器。它是java.util.concurrent.locks包中的基础组件&#xff0c;为多个…

屏幕画面卡住不动声音正常怎么办?电脑屏幕卡住不动解决方法

在数字时代&#xff0c;电脑作为我们日常生活与工作中不可或缺的伙伴&#xff0c;偶尔也会遇到一些小状况。其中&#xff0c;“屏幕画面卡住不动&#xff0c;但是声音依然正常”的情况就是一种常见的问题。本文将探讨这一现象的原因&#xff0c;并提供几种可能的解决方案&#…

FSCapture 9.3 | 全能截图与录屏解决方案。

FastStone Capture 是一款轻量级但功能全面的屏幕捕捉工具&#xff0c;能够轻松捕获并标注屏幕上的一切内容&#xff0c;包括窗口、对象、菜单、全屏、矩形/自由区域以及滚动窗口或网页。此外&#xff0c;它还支持录制屏幕活动、声音和网络摄像头&#xff0c;并将这些内容保存为…

[复现]比较6种股市趋势识别方

作者: Filippos Tzimopoulos 翻译整理&#xff1a;进击的小学生 文章名称: I compared 6 methods to identify the trend of the stock market. These are the results! code 与 datas &#xff0c;请转至获取&#xff01; 背景说明 通过识别市场方向&#xff0c;交易者可…

webAPI中的排他思想、自定义属性操作、节点操作(配大量案例练习)

一、排他操作 1.排他思想 如果有同一组元素&#xff0c;我们想要某一个元素实现某种样式&#xff0c;需要用到循环的排他思想算法&#xff1a; 1.所有的元素全部清除样式 2.给当前的元素设置样式 注意顺序能不能颠倒&#xff0c;首先清除全部样式&#xff0c;再设置自己当前的…

dyna批处理代码,无需蹲守,自行连续计算

用此代码即可 上面一行是模型位置 下面一行是DYNA模拟器位置 第三个框框是K文件名称 上述三者改成自己的 然后复制修改即可 复制几个就几个进行批处理

深入理解伪元素与伪类元素

在“探秘盒子浮动&#xff0c;破解高度塌陷与文字环绕难题&#xff0c;清除浮动成关键&#xff01;”中&#xff0c;我们讲到如果父盒由于各种原因未设置高度&#xff0c; 子盒的浮动会导致父盒的高度塌陷。为了解决高度塌陷的问题&#xff0c;我们可以添加伪元素。 一、伪元素…

Android 内存优化——常见内存泄露及优化方案

看到了一篇关于内存泄漏的文章后&#xff0c;就想着分享给大家&#xff0c;最后一起学习&#xff0c;一起进步&#xff1a; 如果一个无用对象&#xff08;不需要再使用的对象&#xff09;仍然被其他对象持有引用&#xff0c;造成该对象无法被系统回收&#xff0c;以致该对象在…

【element-tiptap】如何修改选中内容时的背景颜色?

前言&#xff1a;element-tiptap 用鼠标选中内容的时候&#xff0c;背景颜色跟系统设置的主题有关&#xff0c;比如的我的就是卡哇伊的pink&#xff0c;默认是淡蓝色 但是我们观察一下语雀&#xff0c;背景颜色是它规定好的颜色 这篇文章来探索一下&#xff0c;怎么自己规定选…