9、(复现)----基于dtw算法的动作、动态识别


# 关键词: DTW动态时间规整 、yolov5、tensorflow加载关键点-检测模型、pytorch加载人物-检测模型,tensorflow训练骨骼关键点检测模型、mediapipe关键点识别、多人2d检测:自上而下(top-down)

# 目标;  
    1、了解人体关键点,和动作、动态识别,
    2、训练自己的关键点检测模型,
    3、基于dtw算法的动作、动态识别!!!

关键点检测:    1、人脸关键点、        2、人体关键点、        3、特定物体、轮廓什么的!
人体骨骼关键点:    Pose Estimation、最热门、最有难度、也是最广泛的!!
    应用:    1、行为识别、2、人机交互、3、智能家居、4、虚拟现实、
    细分:    1、单人、    2、多人、    3、2d、        4、3d

关键点,3类的检测模型:
        1、基于坐标的 coordinate:                【回归模型!】    
            将关键点坐标(采集的训练样本),作为最后网络需要回归的目标(target),
            网络直接得到,每个坐标直接的位置信息。(今天采用的!)
        2、基于heatmap概率图,                    【类似于图像分割】热力图,
            将每一类坐标同一个概率图表示,
            对图中的每一个像素位置,都给一个概率,表示该点属于某个类别---关键点的概率,
            越接近关键点,越接近1;                距离关键点越远,越接近0;
        3、基于heatmap + offset,                heatmap + 偏移: 
            谷歌2017年在 cvpr 提出的!
            更复杂的 heatmap概率图,并且加入了偏移offset..
单人2d检测: 14-20多篇文献
多人2d检测:    1、自上而下(top-down)
            目标检测 + 单人人体骨骼关键点识别:        抠出车牌、检测识别!
        2、自下而上(bottom-up)
            关键点检测 + 关键点聚类:            所有人的点全检测出来,再聚类出来,看看是谁的!
        优劣:    1、自上而下:精度高    2、自下而上:速度快!!!
OpenPose:    经典的《自下而上》!!!


一、训练自己的关键点,检测模型...        tflite在windows上,可能只支持python 3.7
    创建环境:    conda create -n course_action_env python=3.7
    【11:17】    6个关键点,肩膀开始的,6个关节点!!!
            【pytorch下载】
    pip install torch==1.12.1+cu113 torchvision==0.13.1+cu113 torchaudio==0.12.1 --extra-index-url https://download.pytorch.org/whl/cu113
    
    开启,采集脚本,采集自身关节点数据!!!
    采集时、不要在人多的时候采集,以免影响,采集的质量,多人会导致窗口大小不稳定!!!


    1、数据预处理、合成npz文件:
        1、img数据->        resize压缩成128、灰质化、、/255 归一化0-1、reshape增加一个通道数c==1
        2、lable标签->        读取关节点坐标的数据、转为numpy数组、dtype==‘float’
    2、搭建神经网络模型训练:
        不需要onehot独热编码,分类才需要,我们是回归!!!
        # 科学计算包:            pip install scikit-learn
        # 作用:划分测试集、和训练集!!!
        # tensorflow训练包:            pip install tensorflow-gpu==2.6
        # 报错: yolov5环境下,tensorflow绑定设备不显示,
        #  解决: 用自己的 tf2.6的环境,作为替代,切换环境!!     course_action__env  [对应环境!!!]
            1、今天使用的是        tensorflow keras Resnet50        # --可以百度搜索一下架构图、架构、相当复杂!!!
                    # 地址:     https://tensorflow.google.cn/api_docs/python/tf/keras/applications/resnet50/ResNet50
            # action报错!!!无法解读到 cuda设备!!!
                    # weights='imagenet',    可以基于weights='imagenet',预训练的!!!

            2、可以直接使用,keras自带的 resnet50架构,调整:    
                    1、定期存储:保留最好的 loss    2、提前终止: 设置大一点的epoch,loss30次不降自动终止
                    3、动态学习率: 之前都是固定学习率,更好地拟合,        刚开始学习率大,后面越来越小!!!让模型,更好地寻找一些参数!!
                    4、性能好;  增大 batch-size:  64-> 100....
            3、测试训练模型:
                    1、加载模型    2、图片预处理、升维度(人数的参数)        3、模型预测: model.predict(img_input)
                    4、预测结果reshape:result[0].reshape((-1,2))        5、坐标点还原:img_h,img_w = img_raw.shape[:2],乘上、画点!!
            4、转化为 tf_lite,轻量级模型:
                    1、# 构造转换器
                        converter = tf.lite.TFLiteConverter.from_saved_model('./data/enpei_pose_resnet_128/')    
                    2、# 转换
                        tflite_model = converter.convert()    
                    3、# 保存lite
                        with open('./data/enpei_pose_resnet_128.tflite','wb') as f:
                                f.write    (tflite_model)

            # 小插曲: pandas 明明下载了,却引用不了:(解决方式如下 jupyterlab的!!!)
            # 小插曲 : jupyter lab 罢工:
                    
            ImportError: cannot import name 'COMMON_SAFE_ASCII_CHARACTERS' from 'charset_normalizer.constant' (E:\mini\envs\course_action_env\lib\site-packages\charset_normalizer\constant.py)
            # 解决方式:    pip install chardet (修复 jupyter lab!!)
            
            # 训练好的模型,放到3.project/weights/custom_resnet_128 下面
            # code . 直接进入 VScode....

            # 代码:::                【记得】    cd yolov5,    pip install -r requirements.txt,下载 yolov5所需要的依赖!!!
                cd..    
                python ./2.pose_demo_resnet_yolov5.py
            # 经验教训,总结::    最好,寻求一个,tensorflow 和 pytorch 中和的版本,这个环境,需要用到!!!

                1、        # 加载、自定义关键点检测--模型
                    self.pose_model = tf.keras.models.load_model('./weights/custom_resnet_128/best_model_resnet_128.hdf5')
                2、        # 加载、yolov人物检测--模型
                    self.model = torch.hub.load('./yolov5', 'custom', path='./weights/yolov5/yolov5m.pt',source='local')  # local repo

            # 速度较慢;     既要加载yolov5模型(pytorch),又要加载 关键点检测模型(tensorflow!)!!!!
            5、若要再树莓派运行:    yolov5运行不了(pytorch), 用tf_lite 的 ssd_mobilenet 运行,替代检测任务!!
                        完整tensorflow也比较卡,装推理引擎tf_lite,即可,传入压缩后的模型!!!按照步骤即可!!!
                # 报错:        ModuleNotFoundError: No module named 'tflite_runtime'
                # 目录whl:    切入目录,pip install .whl ,即可!!!
                # tflite_runtime 仓库地址:::
                 https://github.com/google-coral/pycoral/releases/download/v1.0.1/tflite_runtime-2.5.0-cp38-cp38-win_amd64.whl#sha256=efcd5605885811b5a967494fdc64bb18b5fde145db12ded3e886fcc42b3666fa
                # 有点卡、3-5帧左右!        原因:        1、加了目标检测,任务多了        2、tflite在win上优化不太好!!!
                # 没板子,烧录过程,直接跳过!!!        大致流程,是: 编译 opencv,安装 tflite的包,等等!!!


二、动作识别 action recognition;
        3个小的细分,分类:
                1、activity:        持续时间较长、长视频的单人或多人行为、        打电话、看书、吃饭、聊天、打球
                2、action:        短时间的行为、短视频片段的单人行为、        鼓掌、接吻、拥抱、扔东西
                3、hand gesture:    单人的手势!    今天类似于这个!!!
        
        动作识别-领域,
            非常大、海康的重点专注领域、因为,它会达到更多的信息抽取!!!
        动作识别-算法分类:
            1、基于骨架的识别,(today的)        
            2、基于视觉的:    
                2.1     two-stream:    特征提取,有两个分支:    1、基于rgb分支的提取的空间特征,2、基于光流分支的提取时间上的光流特征,
                                        最后,结合两种特征,进行动作识别
                2.2    c3d:        3d conv 加入了时间特征,直接将2d conv拓展到了3d,直接提取     时间+空间,两方面特征!!
                2.3    LSTM        使用CNN提取特征,使用RNN提取时间特征(如变种:LSTM),进行行为识别。。

        dtw算法,大致流程:
            1、多动作,分别录制,多个片段视频,提取动作特征,小的特征,
            2、多帧画面,视频流提取,如定期挑选,50帧画面特征,大的特征,        
            3、依次计算、计算大的特征,与小的特征的 DTW 距离!
            4、距离排序,最小的最接近,检查该动作,在m帧画面中,是否满足重复n次,(权重)
            5、满足 >n 条件,预测应该是,某动作!!
        大致:  1、各动作片段视频,提取特征 -> 2、大视频、视频流、提取特征 -> 3、计算视频流中,各动作的 dtw距离 -> 4、由小到大排序 -> 5、最满足筛选条件的,认定为《某动作》!!

    DTW 算法: Dynamic Time Warping ,《动态时间规整 》算法!!!!
            很老的算法,最早用在于语音识别,
            最大作用:    可以计算、两个时间序列的相似度,
                    尤其是,两个时间速度不同的情况,节奏快慢不等的情况下,不同人读一个音频词,不同人走路速度,
            最厉害的是:他会扭曲不同的时间长度,局部缩放较长的时间长度,使得动作时长,尽量相等!!!
                    如: 同一个动作,有时摆的时间长、有时摆的时间短!!!

    1、动作录制:
        脚本录制:    注意、动作要干净、不要夹带无用的动作....

        利用:        各个关节点、构建的其夹角、形成特征 。
                两点相减 == 向量:【后 -前 】                        0-2,2-4 
                夹角 = =两向量的差值,再 arc cos求出来!!!
                    相互之间的夹角:::构成了特征!!!
                不用坐标做特征、选夹角的原因: 坐标会移动、夹角即使目标移动、也可方便稳定计算!

        向量的夹角     cos∠ = (a->*b->) / |a|*|b|
                夹角的cos = 向量的点*积 / 向量的模*积,        在 arc cos,求出夹角!!!
                点积: dot = np.dot(v1,v2)
                模积: norm = np.linalg.norm(v1) * np.linalg.norm(v1)            # 有点像,欧氏距离公式啊!!!
                    return np.acrcos(dot/norm)
                前提: 两向量,方向不一致,既是 ∠ !=0,
                判断方式:    if np.array_equal(v1,v2):    
                            return 0     # 直接返回 夹角 ==0 !!!

    2、代码部分::        难度不大,但是难写,很复杂,时间上也特别耗时,意义不大!
                仅仅作为dtw算法的了解,供后续使用,本次就不再复现了!!大体上陈述几个核心的主要点!
            pip install fastdtw
            from fastdtw import fastdtw
            dis_list = []
            # 遍历动作名称、视频特征    
                distance,path = fastdtw(seq_feat,video_feat)    # 传入序列特征、视频特征
                dis_list.append([action_name,distance])
            # 转为numpy        
            dis_list = np.asarray(dis_list,dytype=object)         # 两个点: 转为numpy,方便排序;既有str,又有float,用object类型,防止报错!!
            # 排序(距离:由低到高)
            dis_list = dis_list[ dis_list[:,1].argsort() ][:self.batch_size]  # 每行的第二列,排序,筛选32帧的前4个(batch_size个)!!m!!!    

            # 排名第一的动作
            first_key  = dis_list[0][0]  
            # 前m次重复次数   
            max_num = np.count_nonzero(dis_list[:,0]==first_key) # 每行第二列中,排名第一动作的重复次数,   m中找n...

            # 是否满足> 阈值n ==2,
            if max_num / batch_size >=0.5:      # 用比例 0.5 表示!!!
                return first_key        # 返还,动作名字!!!
            else:
                return 'unknow!'        # 不满足条件,无法判断!!!
            
      

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值