大兴网站建设公司企业网站更新频率
2026/4/16 1:24:21 网站建设 项目流程
大兴网站建设公司,企业网站更新频率,广东今天新闻最新消息,wordpress删除文章rss目录 前言 1. 效果演示 2. 关键点数据获取与训练 2.1 获取多种关键点检测结果 2.2 关键点JSON文件保存 2.3 将JSON转NPZ 3. 开集分类训练 4. 目标跟踪算法ByteTrack的改进 5. 推理全流程 6. 总结 前言 以“摔倒检测”为例#xff0c;实现一个能够商用的行为识别全流…目录前言1. 效果演示2. 关键点数据获取与训练2.1 获取多种关键点检测结果2.2 关键点JSON文件保存2.3 将JSON转NPZ3. 开集分类训练4. 目标跟踪算法ByteTrack的改进5. 推理全流程6. 总结前言以“摔倒检测”为例实现一个能够商用的行为识别全流程。行为识别数据集可以用作负样本基于关键点的行为识别2 - 动作识别/行为识别/视频分类数据集https://blog.csdn.net/qq_40387714/article/details/155934735算法设计、数据处理逻辑参考基于关键点的行为识别3- 问题分析与算法设计https://blog.csdn.net/qq_40387714/article/details/1559592211. 效果演示本文关键点检测模型选择Ultralytics的yolov8s-pose预训练模型。目标跟踪算法选择改进的ByteTrack我自己引入了关键点信息。行为识别算法选择前文中的PosePointNet。下图中黄色表示追踪算法暂未确定的轨迹绿色表示确定的非摔倒轨迹红色表示摔倒的轨迹。行为识别模型使用约100个视频片段即可训练得到一个差强人意的效果。2. 关键点数据获取与训练1 手动截取视频动作片段动作发生前后1秒钟即可。2用多种关键点检测模型预测出json文件比如yolov8s/m/l/x分辨率设置640、800。3将JSON转成二进制文件方便读取比如NPZ文件里面涉及输入数据预处理。2.1 获取多种关键点检测结果在PoseC3D的论文中做了以下实验低质量关键点训练高质量关键点测试高质量关键点训练低质量关键点测试。以此来说明算法的鲁棒性。这样做是完全没必要的关键点是对视频数据的转换二者并非等价关系。低质量关键点数据必定存在一个视频能够使得高质量检测器也预测为或近似预测为该低质量也许是模糊、遮挡等种种因素导致。反之也成立。更合理的做法直接把不同分辨率的关键点数据混合一起训练。高质量的关键点可以提供高置信度的动作序列低质量的关键点可以扩大输入误差。二者结合可以拓展数据分布降低对姿态估计选型的敏感性。特别地对于低质量关键点如果一个高质量关键点序列可以预测为某一类动作那么当低质量关键点近似接近这个高质量的序列时低质量关键点大概率也是这个类别。很简单的trick我们用yolov8s/m/l/xyolo11/s/m/l/x分别在640和800的分辨率条件下预测一个视频。这样一个视频就获取了16条关键点数据。这样做有两个很明显的好处1. 极大扩充数据集的数量。2. 对姿态估计器和推理分辨率的选择不敏感。部署时用yolov8s还是yolo11s推理图片分辨率变化都不需要去重新训练模型了。UCF101和HMDB51上这样操作yolov8l-pose的准确率可以和FasterRCNNHRNet的准确率相当。NTU和K400上用两种质量的关键点也可以对低质量关键点提升1%的准确率。即便是同一个姿态估计用两种分辨率下预测的关键点训练也要比任意一种单独训练的准确率高。总而言之这是一种可解释性很强的数据增强方式简单相信照着做。2.2 关键点JSON文件保存关键点数据获取时我们应该尽量保留多的推理数据以防想要什么数据又得重新检测了涉及到视频流处理还有频繁的IO操作即使用yolo-pose也很耗时。保存的关键点数据结构如下所示{ video_path: ApplyEyeMakeup/v_ApplyEyeMakeup_g01_c01.avi, video_height: 240, video_width: 320, meta: { fps: 25.0, total_frames: 164, duration: 6.56, source: UCF101, class_id: 0, class_name: ApplyEyeMakeup }, frame_info: { 0: { total_obj: 1, person_box: { 0: { bbox: [0.641968,0.499789,0.715738,0.997828], conf: 0.911277, rgb: [99,95,113], hsv: [119,96,115] } }, person_kpt: { 0: { 0: { kpt: [0.870883,0.367247], conf: 0.977041, rgb: [ [211,196,254] ], hsv: [ [172,58,254] ] }, ...我使用的数据结构除了保存检测框和关键点的坐标置信度外还计算了颜色信息。因为我开始就想将其看做点云来做一个点的颜色可能没有意义但是在整个动作序列中是有的。准确率貌似提高了一点不过最后也没用。一方面是涉及到IO和图像读取生成JSON文件太慢还有就是准确率提高不明显使用的意义不大。具体还需要其他什么特征信息可以根据自己的场景需求去保存。2.3 将JSON转NPZ开源数据集中通常选择2个人我采用面积排序IOU sort的方式实现选人。开源数据集已经引入先验了这个视频中有人做了某个动作且通常占视频主体较大。所以直接选取面积最大的两个人然后用后一帧的检测框去匹配前一帧尽量让第一个人的动作序列完整。我在K400上还做了关键点面积最大、检测框置信度最大、关键点置信度最大等选取方法的测试发现还是面积最大的效果最好。这里尽量要避开置信度的问题因为yolo检测结果有个经验特性检测框能对但置信度差异会很大。自己业务需求的任务选取如“摔倒”、“打架”等需要引入跟踪尽量保证单个动作序列的完整性。在搜集数据时尽量选择单个人且占主体画面的视频这样可以减少后期处理。对于打架这种多人场景的其实只要保证画面中每个人都参与打架了即可。即便只用一个人训练也可以获取较高准确率。选择两个人进行训练效果更稳定。下面是JSON转到NPZ保存的字典np.savez_compressed( out_npz_path, namesnp.array(names, dtypeobject), kp_xynp.array(xs, dtypeobject), kp_confnp.array(cs, dtypeobject), bboxnp.array(bs, dtypeobject), bbox_confnp.array(bcs, dtypeobject), kpt_numint(kpt_num), min_framesint(min_valid_frames), countint(kept) )其实只需要保存最基本的检测框和关键点以及他们的置信度就行。其他信息主要用于可视化检查。3. 开集分类训练和论文中在数据集上已知类别的训练不同实际的分类属于开集数据除了已知类别所有其他未知类别都是负样本类这就导致模型会出现大量误检。未知类别无限多需要优化训练方式。这其实在我前面的文章中已经做过类似的了YOLOv8源码修改1- DataLoader增加负样本数据读取平衡训练batch中的正负样本数https://blog.csdn.net/qq_40387714/article/details/138996317分类模型训练框架搭建1resnet18/50和mobilenetv2在CIFAR10上测试结果https://blog.csdn.net/qq_40387714/article/details/145281204简单来说就是采样负样本训练。我们通常收集的正样本只有几百上千条数据但负样本可以有几万几十万条。可以做以下的操作1.先读取全部数据直接训练不考虑正负样本比例。这样网络实际上会对任意输入都预测为负样本。这一步是让模型简单看一下全部数据且让其对于未知数据就预测为负样本。2.控制正负样本比例训练正样本固定读取负样本控制一定比例抽样读取。这一步是为了能让模型有效学习我们需要识别的类别。3.迭代优化。实际我们会多次采集正样本每次采集完重复步骤2可以让网络见识更多负样本。以下是一个简单的正负样本数据集划分代码def split_pos_and_allocate_negs( pos_keys: Sequence[Tuple[str, Optional[int]]], neg_keys: Sequence[Tuple[str, Optional[int]]], split_ratios: Sequence[float] (0.8, 0.1, 0.1), negative_ratio: float 0.0, seed: int 0, ) - Dict[str, List[Tuple[str, Optional[int]]]]: 先对 pos_keys 做稳健切分最大余数法再用 val_need round(len(val_pos)*negative_ratio) test_need round(len(test_pos)*negative_ratio) 从 neg_keys 中 两次不放回 抽取 val/test 的负样本其余留作训练负样本池。 返回 dict: { train_pos: [...], val_pos: [...], test_pos: [...], val_neg: [...], test_neg: [...], train_neg_pool: [...], } rng random.Random(int(seed)) # 正样本切分打乱后切 pos list(pos_keys) rng.shuffle(pos) n_tr, n_va, n_te compute_split_counts(len(pos), split_ratios) train_pos pos[:n_tr] val_pos pos[n_tr:n_trn_va] test_pos pos[n_trn_va:n_trn_van_te] # 负样本两次不放回 val_need int(round(len(val_pos) * max(0.0, negative_ratio))) test_need int(round(len(test_pos) * max(0.0, negative_ratio))) neg_pool list(neg_keys) rng.shuffle(neg_pool) val_neg neg_pool[:min(val_need, len(neg_pool))] rest neg_pool[len(val_neg):] test_neg rest[:min(test_need, len(rest))] train_neg_pool rest[len(test_neg):] # 训练负样本“大池” return { train_pos: train_pos, val_pos: val_pos, test_pos: test_pos, val_neg: val_neg, test_neg: test_neg, train_neg_pool: train_neg_pool, }4. 目标跟踪算法ByteTrack的改进关键点检测可以同时获取关键点框和关键点多了关键点信息我们就可以对原本的跟踪算法优化一下。这里使用的是YOLOv8中提供的ByteTrack源码DeepSORT同理。我们在tracker/bytetracker/byte_tracker.py中简单修改2处修改1在BYTETracker类的update方法开始处加入形参kpts用来传入关键点数据。修改2在BYTETracker类的update方法return处修改返回值返回原本的信息和关键点信息。该操作主要是用于后续追踪返回信息直接将关键点信息和追踪ID绑定。想要用关键点距离来优化ID Switch问题只需在下面匹配中引入一定规则即可5. 推理全流程步骤1使用YOLO-pose获取关键点# 2) YOLO Pose pose_model YOLO(modelcfg.YOLO_POSE_WEIGHTS, taskpose) # YOLO Pose 检测 res pose_model.predict(frame, imgsz640, verboseFalse, confcfg.DET_CONF)[0]步骤2使用目标跟踪分配跟踪IDdet_boxes res.boxes.xyxy.cpu().numpy().astype(np.float32) # (N,4) det_confs res.boxes.conf.cpu().numpy().astype(np.float32) # (N,) det_cls res.boxes.cls.cpu().numpy().astype(np.int32) # (N,) det_kpts np.concatenate([k_xy, k_cf[..., None]], axis-1).astype(np.float32) # (N,V,3), COCO-pose V17 # ByteTrackWrapper out_trk bytetrack.update(det_boxes, det_confs, det_cls, det_kpts)步骤3使用双端队列构建行为识别模型输入tracks_now: List[Dict] out_trk.get(tracks, []) or [] pack_ids: List[int] out_trk.get(pack_ids, []) or [] xg out_trk.get(xg, None) xl out_trk.get(xl, None) dropped_ids: List[int] out_trk.get(dropped_ids, []) or [] xg_in xg[infer_idx].astype(np.float32) xl_in xl[infer_idx].astype(np.float32) logits sess.run([out_name], {xg_name: xg_in, xl_name: xl_in})[0] # (B,C) probs _softmax_np(logits, axis1) # (B,C)这里我采用了以下逻辑为每个ID维护一个双端队列每当获取一个检测结果检测框、关键点、置信度如果队列未满就把结果压入双端队列否则先弹出一个最老结果再压入。当前ID被检测到且双端队列中数据长度大于等于队列长度一半且推理间隔满足步长stride则将整个队列传入行为识别模型。我的模型是双输入模型包含xg和归一化的结果xl。当追踪ID被丢弃则双端队列中的ID也丢弃。参数设置T32。推理序列最大长度。STRIDE1。推理间隔1为每帧都推理。追踪算法采用yolov8中ByteTrack的默认参数。6. 总结训练和推理框架搭建完成后整个流程难度仍然在数据采集上。需要保证每个类别数据的尽量不包含不属于该类别的动作。其余动作的识别如“站立”、“行走”、“奔跑”、“深蹲”、“坐着”、“趴着”可以一样实现识别。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询