基于华为atlas环境下的OpenPose人体关键点检测的人员跨越、坐立检测

整体思路:

收集数据集,数据集中包含3种类型的数据,分别是跨越、坐立、其他(站立、睡着等等)。3种类型的数据样本量持平。

首先基于OpenPose进行人体关键点的检测,得到人体的18个关键点。然后基于该算法将上面的数据集跑一遍,得到所有数据的人体关键点和类别。基于该识别结果输入xgboost模型进行3分类训练,得到最终的输出结果。

数据集准备:

跨越数据,类别为0

坐立数据,类别为1

其他类型数据,类别为2

mxpiOpenposeProto库的编译:

这里使用的protoc是3.14.0的版本,protobuf是3.19.0的版本

cd proto
bash build.sh

后处理插件编译:

cd plugins
bash build.sh
chmod 440 build/libmxpi_openposepostprocess.so
cp build/libmxpi_openposepostprocess.so ${SDK_INSTALL_PATH}/mxVision/lib/plugins/ # ${SDK_INSTALL_PATH}替换为用户的SDK安装路径

模型转化:

atc --model=./simplified_560_openpose_pytorch.onnx --framework=5 --output=openpose_pytorch_560 --soc_version=Ascend310P3 --input_shape="data:1, 3, 560, 560" --input_format=NCHW --insert_op_conf=./insert_op.cfg

推理代码实现:

import sys
import os
import enumimport numpy as np
import cv2
import timefrom StreamManagerApi import StreamManagerApi, MxDataInput, StringVector
sys.path.append("../proto")
import mxpiOpenposeProto_pb2 as mxpiOpenposeProtofrom xgb import XGBCOCO_PAIRS = [(1, 2), (1, 5), (2, 3), (3, 4), (5, 6), (6, 7), (1, 8), (8, 9), (9, 10), (1, 11),(11, 12), (12, 13), (1, 0), (0, 14), (14, 16), (0, 15), (15, 17), (2, 16), (5, 17)]  # = 19COCO_PAIRS_RENDER = COCO_PAIRS[:-2]COCO_COLORS = [[255, 0, 0], [255, 85, 0], [255, 170, 0], [255, 255, 0], [170, 255, 0], [85, 255, 0], [0, 255, 0],[0, 255, 85], [0, 255, 170], [0, 255, 255], [0, 170, 255], [0, 85, 255], [0, 0, 255], [85, 0, 255],[170, 0, 255], [255, 0, 255], [255, 0, 170], [255, 0, 85]]class OPENPOSE(object):def __init__(self):# init stream managerself.stream_manager_api = StreamManagerApi()ret = self.stream_manager_api.InitManager()if ret != 0:print("Failed to init Stream manager, ret=%s" % str(ret))exit()# create streams by pipeline config filewith open("./pipeline/Openpose.pipeline", "rb") as f:pipeline_str = f.read()ret = self.stream_manager_api.CreateMultipleStreams(pipeline_str)if ret != 0:print("Failed to create Stream, ret=%s" % str(ret))exit()#跨越、坐立预测self.xgb = XGB()def preproc(self, img, img_size, swap=(2, 0, 1)):h,w = img.shape[:2]h_ratio = img_size[0] / img.shape[0]w_ratio = img_size[1] / img.shape[1]resized_img = cv2.resize(img,(img_size[1], img_size[0]),interpolation=cv2.INTER_AREA,).astype(np.uint8)return resized_img, h_ratio, w_ratiodef get_pose_bbox(self, person_list, h_ratio, w_ratio):joints, xcenter = [], []for person in person_list:skeletons = person.skeletonInfoVecx_coords, y_coords, centers = [], [], {}seen_idx = []for skele in skeletons:part_idx1 = skele.cocoSkeletonIndex1part_idx2 = skele.cocoSkeletonIndex2if part_idx1 not in seen_idx:seen_idx.append(part_idx1)center = (int(skele.x0 / w_ratio), int(skele.y0 / h_ratio))centers[part_idx1] = centerx_coords.append(center[0])y_coords.append(center[1])if part_idx2 not in seen_idx:seen_idx.append(part_idx2)center = (int(skele.x1 / w_ratio), int(skele.y1 / h_ratio))centers[part_idx2] = centerx_coords.append(center[0])y_coords.append(center[1])joints.append(centers)return jointsdef draw(self, npimg, results):for joint in results:minx, miny = -1,-1for key, value in joint["joint"].items():# draw keypointscenter = valuecv2.circle(npimg, center, 3, COCO_COLORS[key], thickness=3, lineType=8, shift=0)if minx==-1 and miny==-1:minx = center[0]miny = center[1]# draw skeletonsfor pair_order, pair in enumerate(COCO_PAIRS_RENDER):if pair[0] not in joint["joint"].keys() or pair[1] not in joint["joint"].keys():continuecv2.line(npimg, joint["joint"][pair[0]], joint["joint"][pair[1]], COCO_COLORS[pair_order], 3, cv2.LINE_AA)label = joint["pred_label"] +" {:.3f}".format(joint["prob"])cv2.putText(npimg, label, (minx, miny), 0, 0.6, (255,255,255), thickness=1, lineType=cv2.LINE_AA)return npimgdef process(self, image):stream_name = b"classification+detection"in_plugin_id = 0h0, w0 = image.shape[:2]input_shape = (560, 560)pre_img, h_ratio, w_ratio = self.preproc(image, input_shape)pre_img = np.ascontiguousarray(pre_img)image_bytes = cv2.imencode('.jpg', pre_img)[1].tobytes()data_input = MxDataInput()data_input.data = image_bytesunique_id = self.stream_manager_api.SendData(stream_name, in_plugin_id, data_input)if unique_id < 0:print("Failed to send data to stream.")exit()keys = [b"mxpi_openposepostprocess0"]key_vec = StringVector()for key in keys:key_vec.push_back(key)infer_result = self.stream_manager_api.GetProtobuf(stream_name, in_plugin_id, key_vec)if infer_result.size() == 0:print("infer_result is null")exit()if infer_result[0].errorCode != 0:print("infer_result error. errorCode=%d" % (infer_result[0].errorCode))exit()result_personlist = mxpiOpenposeProto.MxpiPersonList()result_personlist.ParseFromString(infer_result[0].messageBuf)detect_person_list = result_personlist.personInfoVecjoints  = self.get_pose_bbox(detect_person_list, h_ratio, w_ratio)results = []for joint in joints:joint_np = np.ones((1,36))*(-1)for i in range(18):if i in joint.keys():joint_np[0,2*i] = joint[i][0]joint_np[0,2*i+1] = joint[i][1]pred, pred_prob, pred_label = self.xgb.pred(joint_np)results.append({"joint":joint, "pred":pred, "prob":pred_prob, "pred_label":pred_label})return resultsdef __del__(self):# destroy streamsself.stream_manager_api.DestroyAllStreams()def test_image():openpose = OPENPOSE()file_name = "./images/1.jpg"image = cv2.imread(file_name, 1)results = openpose.process(image)print("#####", results)image_show = openpose.draw(image, results)cv2.imwrite(file_name.split('.')[0] + "_detect_result.jpg", image_show)def test_images():openpose = OPENPOSE()data_dir = "./data/other/"#data_dir = "./data/sit/"#data_dir = "./data/span/"for name in os.listdir(data_dir):fullname = os.path.join(data_dir, name)image = cv2.imread(fullname, 1)joints = openpose.process(image)#print(name, joints)for joint in joints:out = ""+name +" 2"for i in range(18):if i in joint["joint"].keys():out = out + " "+ str(joint["joint"][i][0]) + " " + str(joint["joint"][i][1])else:out = out+" -1 -1"print(out)#image_show = openpose.draw(image, joints)#cv2.imwrite(name, image_show)def test_video():openpose = OPENPOSE()# Open the video filevideo_path = "./images/span.mp4"cap = cv2.VideoCapture(video_path)fourcc = cv2.VideoWriter_fourcc('X', 'V', 'I', 'D') # 确定视频被保存后的编码格式output = cv2.VideoWriter("output.mp4", fourcc, 20, (640, 480)) # 创建VideoWriter类对象# Loop through the video frameswhile cap.isOpened():# Read a frame from the videosuccess, frame = cap.read()if success:# Run YOLOv8 tracking on the frame, persisting tracks between framest1 = time.time()results = openpose.process(frame)t2 = time.time()annotated_frame = openpose.draw(frame, results)print("time", t2-t1)output.write(annotated_frame)# Break the loop if 'q' is pressedif cv2.waitKey(1) & 0xFF == ord("q"):breakelse:# Break the loop if the end of the video is reachedbreak# Release the video capture object and close the display windowcap.release()cv2.destroyAllWindows()if __name__ == '__main__':#test_image()test_images()#test_video()

模型识别效果:

Xgboost数据集准备:

基于OpenPose模型将数据集跑一遍,得到关键点坐标数据集,数据集保存在txt里面,每一行格式为(图片名 类别 关键点xy坐标),如果身体遮挡没有关键点的使用-1代替。

Xgboost模型训练:

训练代码,

import xgboost
from xgboost import XGBClassifier
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
#from sklearn.externals import joblib
import joblib
import numpy as np
from matplotlib import pyplot as plt
import osfrom matrix import DrawConfusionMatrix
data_label = ["span", "sit", "other"]
drawconfusionmatrix = DrawConfusionMatrix(labels_name=data_label)def train():# 载入数据集dataset = np.loadtxt('./data/all.txt', delimiter=" ", usecols=list(range(1,38)))X = dataset[:, 1:]Y = dataset[:, 0]"""#数据归一化x = X[:,0:36:2].copy()y = X[:,1:36:2].copy()maxx = np.max(x, axis=1).reshape(-1,1)x[x==-1]=10000minx = np.min(x, axis=1).reshape(-1,1)maxy = np.max(y, axis=1).reshape(-1,1)y[y==-1]=10000miny = np.min(y, axis=1).reshape(-1,1)minxy = np.hstack([minx, miny])maxxy = np.hstack([maxx, maxy])minxy = np.tile(minxy,(1,18))maxxy = np.tile(maxxy,(1,18))X = (X - minxy)/(maxxy-minxy)"""# 把数据集拆分成训练集和测试集seed = 7test_size = 0.15X_train, X_test, y_train, y_test = train_test_split(X, Y, test_size=test_size, random_state=seed)evalset = [(X_train, y_train), (X_test, y_test)]model = XGBClassifier(max_depth=2, num_class=3, learning_rate=0.1, n_estimators=300, silent=True, reg_alpha=0.01, objective='multi:softprob')model.fit(X_train, y_train, eval_metric=['mlogloss','merror'], eval_set = evalset, verbose=True)results = model.evals_result()plt.plot(results["validation_0"]["mlogloss"], label="train", linestyle="solid", color='k')plt.plot(results["validation_1"]["mlogloss"], label="test", linestyle="dotted", color='k')plt.legend()plt.xlabel('epoch')plt.ylabel('loss')plt.savefig("loss.png")plt.plot(1.0-np.array(results["validation_0"]["merror"]), label="train", linestyle="solid", color='k')plt.plot(1.0-np.array(results["validation_1"]["merror"]), label="test", linestyle="dotted", color='k')plt.legend()plt.xlabel('epoch')plt.ylabel('accuracy')plt.savefig("acc.png")# 保存模型joblib.dump(model, "xg.model") # 加载模型model = joblib.load("xg.model")# 对测试集做预测y_pred = model.predict(X_test)predictions = [round(value) for value in y_pred]y_pred_prob = model.predict_proba(X_test)#混淆矩阵drawconfusionmatrix.update(np.array(predictions,np.int32), y_test.astype(np.int32))drawconfusionmatrix.drawMatrix()# 评估预测结果accuracy = accuracy_score(y_test, predictions)print("Accuracy: %.2f%%" % (accuracy * 100.0))def test():xgb = XGB()data = "283 183 271 225 244 224 226 285 272 309 297 226 296 282 300 304 246 323 333 345 296 435 281 318 350 348 294 435 275 175 289 176 263 182 297 183"data = data.split(" ")x_test = np.array(data,np.float32).reshape(-1, 36)predictions, predictions_label = xgb.pred(x_test)print(predictions, predictions_label)class XGB():def __init__(self):self.model = joblib.load("./models/xg.model")self.data_label = {0:"span", 1:"sit", 2:"other"}def pred(self, X_test):#pred = self.model.predict(X_test)[0]pred_prob = self.model.predict_proba(X_test)[0]pred = int(np.argmax(pred_prob))pred_prob = pred_prob[pred]pred_label = self.data_label[pred]return pred, pred_prob, pred_labelif __name__ == "__main__":train()#test()

训练结果,

整体测试:

整体感受:

(1)目前基于该方法有一定的效果,精度不高主要还是因为训练数据太少。关键点模型也是直接使用的开源的模型,没有在自己私有数据上微调,等等问题都会对最终的结果有影响。

(2)本质来看,跨越、坐立还是一个时序问题,基于时序的思路解答这个问题效果应该是会高一个量级的。但是时序的模型一般都大,过程复杂,效率偏低,工程视频实时推理使用又不实际。

参考链接:

https://github.com/Daniil-Osokin/lightweight-human-pose-estimation.pytorch

https://gitee.com/ascend/mindxsdk-referenceapps/tree/master/contrib/OpenposeKeypointDetection

快速安装昇腾环境 — 昇腾开源 1.0 文档

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

ubuntu20.04 加固方案-设置限制su命令用户组

一、编辑/etc/pam.d/su配置文件 打开终端。 使用文本编辑器&#xff08;如vim&#xff09;编辑/etc/pam.d/su文件。 vim /etc/pam.d/su 二、添加配置参数 在打开的配置文件的中&#xff0c;添加以下参数&#xff1a; auth required pam_wheel.so 创建 wheel 组 并添加用户 …

迅为itop-3568开发板AMP双系统使用手册之烧写AMP镜像

瑞芯微RK3568芯片是一款定位中高端的通用型SOC&#xff0c;采用22nm制程工艺&#xff0c;搭载一颗四核Cortex-A55处理器和Mali G52 2EE 图形处理器。RK3568 支持4K 解码和 1080P 编码&#xff0c;支持SATA/PCIE/USB3.0 外围接口。RK3568内置独立NPU&#xff0c;可用于轻量级人工…

2024 年最佳解压缩软件免费下载推荐

在如今的信息时代&#xff0c;解压缩软件对于处理各种压缩文件至关重要。随着互联网的飞速发展&#xff0c;我们在日常工作和生活中会接触到大量的文件&#xff0c;而很多时候这些文件会以压缩的形式进行传输和存储。 对于个人用户而言&#xff0c;解压缩软件能够帮助我们轻松…

MySQL数据库之存储过程的创建与应用

存储过程 procedure 一.存储过程 作用&#xff1a;将经常使用的功能写成存储过程&#xff0c;方便后续重复使用。 二.创建存储过程 三.调用存储过程 call在计算机中是调用的意思 案例1&#xff1a;查看MySQL用户数 如上图所示&#xff0c;这是查看MySQL数据库中的user个数…

JAVA:数据库(mysql)编程初步学习\JDBC(附带项目文件)

给入门的同学初步了解JDBC&#xff0c;本人学疏才浅也希望可以给新人启发&#xff0c;编程的函数比较简单没有用更多库&#xff0c;方便给新人一个舒适的理解 tips&#xff1a;附带编程全套的代码&#xff0c;欢迎大家自由使用,仅供学习&#xff01; &#xff08;文件代码几千…

网页上视频没有提供下载权限怎么办?

以腾讯会议录屏没有提供下载权限为例&#xff0c;该怎么办呢&#xff1f; 最好的办法就是找到管理员&#xff0c;开启下载权限。如果找不到呢&#xff0c;那就用这个办法下载。 1.打开Microsoft Edge浏览器的扩展 2.搜索“视频下载”&#xff0c;选择“视频下载Pro” 3.点击“…

第15课 算法(下)

掌握冒泡排序、选择排序、插入排序、顺序查找、对分查找的的基本原理&#xff0c;并能使用这些算法编写简单的Python程序。 一、冒泡排序 1、冒泡排序的概念 冒泡排序是最简单的排序算法&#xff0c;是在一列数据中把较大&#xff08;或较小&#xff09;的数据逐次向右推移的…

USB摄像头使用V4L2采集图像\视频

背景 V4L2&#xff08;Video for Linux Two&#xff09;是Linux内核自带的一部分&#xff0c;专门用于处理视频设备的管理和控制。‌ V4L2框架提供了统一的API和抽象层&#xff0c;使得开发者可以编写通用的视频驱动程序&#xff0c;同时使用户空间的应用程序能够轻松地访问和…

栈和队列(三)

队列的链式存储表示和实现 链队的类型定义 typedef struct qnode{char data;struct qnode *next; }qnode,*queneptr;typedef struct{queneptr front;queneptr rear; }linkqueue; typedef struct qnode{}&#xff1a; 定义了一个名为qnode的结构体。结构体成员包括&#xff1a…

vmvare启动freebsd操作系统密码忘记了怎么办?

本章教程,主要介绍,通过vmvare安装的freebsd操作系统,密码忘记了,如何重置密码。 一、重启虚拟机 在重启过程中,按键盘中是数字2,进入单用户模式。 二、进入到shell界面 在出现“Enter full pathname of shell or RETURN for /bin/sh:”直接按回车键。 三、输入命令 mou…

设计模式之结构型模式---装饰器模式

目录 1.概述2.类图3.应用场景及优缺点3.1 应用场景3.2 优缺点3.2.1 优点3.2.2 缺点 4.实现4.1 案例类图4.2 代码实现4.2.1 定义抽象构建角色4.2.2 定义具体构建角色4.2.3 定义抽象装饰器角色4.2.4 定义具体装饰角色4.2.5 装饰器模式的使用 1.概述 装饰器模式是指在不改变现有对…

SQL,力扣题目1709,访问日期之间最大的空档期

一、力扣链接 LeetCode_1709 二、题目描述 表&#xff1a; UserVisits ------------------- | Column Name | Type | ------------------- | user_id | int | | visit_date | date | ------------------- 该表没有主键&#xff0c;它可能有重复的行 该表包含用户访问…

极市平台 | NeurIPS 2024|浙大/微信/清华提出:彻底解决扩散模型反演问题

本文来源公众号“极市平台”&#xff0c;仅用于学术分享&#xff0c;侵权删&#xff0c;干货满满。 原文链接&#xff1a;NeurIPS 2024&#xff5c;浙大/微信/清华提出&#xff1a;彻底解决扩散模型反演问题 极市导读 本文介绍了浙江大学、微信和清华大学联合提出的BELM算法…

心觉:人每日60000念头,如何让你的时间精力只专注于核心目标?

Hi&#xff0c;我是心觉&#xff0c;带你用潜意识化解各种焦虑、内耗&#xff0c;建立无敌自信&#xff1b;教你财富精准显化的实操方法&#xff1b;关注我,伴你一路成长&#xff01; 每日一省写作220/1000天 据说一个人每天会产生60000个念头 有些我们的意识能察觉到&#x…

89.冒泡算法(代码编写)

目录 一.代码编写 二.视频教程 一.代码编写 #include <stdio.h>void main(void) {int data[10];int j,i;int temp;printf("Please input data:\n");for(i0;i<10;i){scanf("%d",&data[i]);}for(i0;i<10;i){for(j0;j<9-i;j){if(data[j…

SQL CASE表达式与窗口函数

CASE 表达式是一种通用的条件表达式&#xff0c;类似于其他编程语言中的if/else语句。 窗口函数类似于group by&#xff0c;但是不会改变记录行数&#xff0c;能扫描所有行&#xff0c;能对每一行执行聚合计算或其他复杂计算&#xff0c;并把结果填到每一行中。 1 CASE 表达式…

ubuntu22-安装vscode-配置shell命令环境-mac安装

文章目录 1.安装vscode2.修改语言为中文3.配置bash调试环境3.1.安装插件3.2.添加配置文件 4.调试bash4.1.新建tmp.sh文件4.2.运行启动 5.mac安装6.mac卸载 1.安装vscode 从官网下载安装包Code_1.93.1-1726079302_amd64.deb。 在ubuntu系统中&#xff0c;安装包所在目录打开命令…

Chromium127编译指南 Linux篇 - 同步第三方库以及Hooks(六)

引言 在成功克隆 Chromium 源代码仓库并建立新分支之后&#xff0c;配置开发环境成为至关重要的下一步。这一过程涉及获取必要的第三方依赖库以及设置钩子&#xff08;hooks&#xff09;&#xff0c;这些步骤对于确保后续的编译和开发工作能够顺利进行起着决定性作用。本指南旨…

【NOIP提高组】虫食算

【NOIP提高组】虫食算 C语言C &#x1f490;The Begin&#x1f490;点点关注&#xff0c;收藏不迷路&#x1f490; 所谓虫食算&#xff0c;就是原先的算式中有一部分被虫子啃掉了&#xff0c;需要我们根据剩下的数字来判定被啃掉的字母。来看一个简单的例子&#xff1a; 43#98…

练习LabVIEW第三十题

学习目标&#xff1a; 刚学了LabVIEW&#xff0c;在网上找了些题&#xff0c;练习一下LabVIEW&#xff0c;有不对不好不足的地方欢迎指正&#xff01; 第三十题&#xff1a; 用labview写一个获取当前系统时间的程序 开始编写&#xff1a; 前面板添加一个字符串显示控件&am…