python项目学习 mediapipe手势识别 opencv可视化显示

import cv2
import mediapipe
import numpy

def get_angle(vector1,vector2):#角度计算
    angle = numpy.dot(vector1, vector2) / (numpy.sqrt(numpy.sum(vector1 * vector1)) * numpy.sqrt(numpy.sum(vector2 * vector2)))#cos(angle)=向量的点乘/向量的模
    angle=numpy.arccos(angle)/3.14*180#angle=arccos(angle) 弧度=(angle/3.14)*180
    return angle
def gesture(judge_finger,finger_list):#手势规则
    if len(judge_finger)==1 and judge_finger[0]==8:
        vector1=finger_list[6]-finger_list[7]#向量计算
        vector2=finger_list[8]-finger_list[7]
        angle=get_angle(vector1,vector2)
        if angle<170:
            gesture_str="9"
        else:
            gesture_str="1"
    elif len(judge_finger)==2 and judge_finger[0]==8 and judge_finger[1]==12:
        gesture_str="2"
    elif len(judge_finger)==2 and judge_finger[0]==4 and judge_finger[1]==20:
        gesture_str="6"
    elif len(judge_finger)==2 and judge_finger[0]==4 and judge_finger[1]==8:
        gesture_str="8"
    elif len(judge_finger)==3 and judge_finger[0]==8 and judge_finger[1]==12 and judge_finger[2]==16:
        gesture_str="3"
    elif len(judge_finger)==3 and judge_finger[0]==4 and judge_finger[1]==8 and judge_finger[2]==12:
        gesture_str="7"
    elif len(judge_finger)==4 and judge_finger[0]==8 and judge_finger[1]==12 and judge_finger[2]==16 and judge_finger[3]==20:
        gesture_str="4"
    elif len(judge_finger) == 5 and judge_finger[0] == 4 and judge_finger[1] == 8 and judge_finger[2] == 12 and judge_finger[3] == 16 and judge_finger[4] == 20:
        gesture_str="5"
    elif len(judge_finger)==0:
        gesture_str="10"
    elif len(judge_finger)==1 and judge_finger[0]==4:
        gesture_str="yyds"
    elif len(judge_finger)==1 and judge_finger[0]==20:
        gesture_str="so what?"
    elif len(judge_finger)==1 and judge_finger[0]==12:
        gesture_str="fuck you"
    else:
        gesture_str="?"
    return gesture_str

if __name__ == '__main__':
    open_camera=cv2.VideoCapture(0)#打开笔记本内置摄像头
    #定义检测对象
    hand=mediapipe.solutions.hands#手部识别器
    hand_detector=hand.Hands()#手部关键点检测器 使用默认参数
    mediapipe_draw=mediapipe.solutions.drawing_utils#绘图模块
    while True:
        #读取图像 初始化
        success,image=open_camera.read()#参数success 为True 或者False,代表有没有读取到图片 参数image表示截取到一帧的图片
        image=cv2.flip(image,1)#镜像反转image
        image_height,image_width,image_channels=image.shape#height 表示图像的高度(垂直方向上的像素数) width 表示图像的宽度(水平方向上的像素数) channels 表示图像的通道数
        if success:
            imageRGB=cv2.cvtColor(image,cv2.COLOR_BGR2RGB)#转换为rgb图像
            resule=hand_detector.process(imageRGB)#process 接收RGB格式的numpy数组,返回<class 'mediapipe.python.solution_base.SolutionOutputs'>
            #print(resule)
            #手部关键点抓取可视化输出
            if resule.multi_hand_landmarks: #multi_hand_landmarks 被检测/跟踪的手的集合,其中每只手被表示为21个手部地标的列表,每个地标由x、y和z组成
                hand_point=resule.multi_hand_landmarks[0]#只识别一只手
                mediapipe_draw.draw_landmarks(image,hand_point,hand.HAND_CONNECTIONS)#将识别到的手部关键点连线绘制到cv2图像中
                #print(resule.multi_hand_landmarks)#量化的关键点坐标

                #手势识别判断依据计算
                finger_list = []#存储关键点坐标
                for i in range(21):#关键点坐标计算
                    point_x=hand_point.landmark[i].x*image_width
                    point_y = hand_point.landmark[i].y * image_height
                    finger_list.append([int(point_x), int(point_y)])
                finger_list=numpy.array(finger_list, dtype=numpy.int32)#list转换为numpy.ndarray 采集关键点坐标
                #print(finger_list)
                irrelevant_index=[0,1,2,3,6,10,14,19,18,17,10]# 关键点[0,1,2,3,6,10,14,19,18,17,10]作一个无关组
                irrelevant=cv2.convexHull(finger_list[irrelevant_index])#cv2.convexHull 构造无关组凸包
                #print("无关组:",irrelevant)
                cv2.polylines(image,[irrelevant],True,(255,255,255),2, cv2.LINE_AA)#绘制无关组凸包
                judge_list=[4,8,12,16,20]# 以检测关键点[4,8,12,16,20]有无在凸包外作为识别判断依据
                judge_finger=[]#存储识别关键点
                for index in judge_list:
                    finger=(int(finger_list[index][0]), int(finger_list[index][1]))#计算识别关键点坐标
                    #print("判断关键点:",finger)
                    judge=cv2.pointPolygonTest(irrelevant,finger,True)#检测识别关键点有无在凸包内
                    if judge<0:#不在凸包内
                        judge_finger.append(index)

                #手势判断
                gesture_str=gesture(judge_finger,finger_list)
                cv2.putText(image,gesture_str,(100,100),cv2.FONT_HERSHEY_SIMPLEX,3,(255,255,255),2,cv2.LINE_AA)#手势意思可视化

        cv2.imshow("gesture detector",image)
        key=cv2.waitKey(1)#cv.waitKey()是一个键盘绑定函数
        if key==ord('q'):#等待'q'键 退出
            break
    open_camera.release()

运行结果

  • 18
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值