0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

使用KeyPointRCNN轻松获取人体的17个关键点

OpenCV学堂 来源:OpenCV学堂 作者:gloomyfish 2022-10-14 17:33 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

前言

TorchVision支持主流姿态评估模型关键点检测模型KeyPointRCNN,通过它可以轻松获取人体的17个关键点,跟OpenPose等模型相比,KeyPointRCNN基于TorchVision框架,迁移学习训练简单,支持一键导出ONNX格式,可以部署到ONNXRUNTIME与OpenVINO,支持C++PythonSDK部署,可以说在易用性上丝毫不差!

14a3e83c-4b9d-11ed-a3b6-dac502259ad0.jpg

KeyPointRCNN模型介绍

Torchvision中KeyPointRCNN已经是基于2021年的论文中的最新版本,效果非常好,2021年论文比2019论文最大的改动在预测的编码与解码部分,提出了CIF与CAF两种新的编码方法,模型结构图示如下:

14ebe696-4b9d-11ed-a3b6-dac502259ad0.png

上述一段英文交代的比较清楚,模型输入就是一张RGB彩色图像,模型最终的输出有四个部分组成,分别是boxes、labels、scores、keypoints,它们的输出结构如下:

15bba5ca-4b9d-11ed-a3b6-dac502259ad0.png

不是还有最后一个输出层没有解释吗,最后一个输出层其实是各个关键点的得分信息,小于的基本上应该都被干掉,不可信。

另外KeyPoint部分输出是17x3,3表示x、y、v其中v表示是否可见,v为1表示该关键点可见、v为0表示该关键点不可见。 各个关节点的连接顺序与编码坐标如下(写代码有用的):

27b1581a-4b9d-11ed-a3b6-dac502259ad0.png

27dd11da-4b9d-11ed-a3b6-dac502259ad0.png

KeyPointRCNN推理演示

Torchvision官方提供了预训练的模型,直接下载之后,通过下面的脚本就可以转换为ONNX格式模型,然后通过ONNXRUNTIME就可以完成推理演示。

第一步,转ONNX格式

相关脚本如下

model=torchvision.models.detection.keypointrcnn_resnet50_fpn(weights=KeypointRCNN_ResNet50_FPN_Weights.DEFAULT)
model.eval()
x=[torch.rand(3,300,400),torch.rand(3,500,400)]
predictions=model(x)

#optionally,ifyouwanttoexportthemodeltoONNX:
torch.onnx.export(model,x,"keypoint_rcnn.onnx",opset_version=11)
如果不工作,请参考这里的转换脚本修改之: TorchVision对象检测RetinaNet推理演示

第二步:ONNRUNTIME推理演示

这部分跟之前发过一篇RetinaNet推理文章非常相似,这篇文章的连接如下,代码只是稍微改了那么一点点,增加了KeyPoint部分的可视化,推理部分的代码如下:
importonnxruntimeasort
importcv2ascv
importnumpyasnp
importtorchvision

coco_names={'0':'background','1':'person','2':'bicycle','3':'car','4':'motorcycle','5':'airplane','6':'bus',
'7':'train','8':'truck','9':'boat','10':'trafficlight','11':'firehydrant','13':'stopsign',
'14':'parkingmeter','15':'bench','16':'bird','17':'cat','18':'dog','19':'horse','20':'sheep',
'21':'cow','22':'elephant','23':'bear','24':'zebra','25':'giraffe','27':'backpack',
'28':'umbrella','31':'handbag','32':'tie','33':'suitcase','34':'frisbee','35':'skis',
'36':'snowboard','37':'sportsball','38':'kite','39':'baseballbat','40':'baseballglove',
'41':'skateboard','42':'surfboard','43':'tennisracket','44':'bottle','46':'wineglass',
'47':'cup','48':'fork','49':'knife','50':'spoon','51':'bowl','52':'banana','53':'apple',
'54':'sandwich','55':'orange','56':'broccoli','57':'carrot','58':'hotdog','59':'pizza',
'60':'donut','61':'cake','62':'chair','63':'couch','64':'pottedplant','65':'bed',
'67':'diningtable','70':'toilet','72':'tv','73':'laptop','74':'mouse','75':'remote',
'76':'keyboard','77':'cellphone','78':'microwave','79':'oven','80':'toaster','81':'sink',
'82':'refrigerator','84':'book','85':'clock','86':'vase','87':'scissors','88':'teddybear',
'89':'hairdrier','90':'toothbrush'}

transform=torchvision.transforms.Compose([torchvision.transforms.ToTensor()])

sess_options=ort.SessionOptions()
#Belowisforoptimizingperformance
sess_options.intra_op_num_threads=24
#sess_options.execution_mode=ort.ExecutionMode.ORT_PARALLEL
sess_options.graph_optimization_level=ort.GraphOptimizationLevel.ORT_ENABLE_ALL
ort_session=ort.InferenceSession("keypointrcnn_resnet50_fpn.onnx",sess_options=sess_options,
providers=['CUDAExecutionProvider'])
src=cv.imread("D:/images/messi_player.jpg")
cv.namedWindow("KeyPointRCNNDetectionDemo",cv.WINDOW_AUTOSIZE)
image=cv.cvtColor(src,cv.COLOR_BGR2RGB)
blob=transform(image)
c,h,w=blob.shape
input_x=blob.view(1,c,h,w)
defto_numpy(tensor):
returntensor.detach().cpu().numpy()iftensor.requires_gradelsetensor.cpu().numpy()

#computeONNXRuntimeoutputprediction
ort_inputs={ort_session.get_inputs()[0].name:to_numpy(input_x)}
ort_outs=ort_session.run(None,ort_inputs)
#(N,4)dimensionalarraycontainingtheabsolutebounding-box
boxes=ort_outs[0]
#labels
labels=ort_outs[1]
#scores
scores=ort_outs[2]
#key_points
multi_key_points=ort_outs[3]

print(boxes.shape,boxes.dtype,labels.shape,labels.dtype,scores.shape,scores.dtype,multi_key_points.shape)

index=0
forx1,y1,x2,y2inboxes:
ifscores[index]>0.5:
cv.rectangle(src,(np.int32(x1),np.int32(y1)),
(np.int32(x2),np.int32(y2)),(140,199,0),2,8,0)
label_id=labels[index]
label_txt=coco_names[str(label_id)]
cv.putText(src,label_txt,(np.int32(x1),np.int32(y1)),cv.FONT_HERSHEY_SIMPLEX,0.75,(0,0,255),1)
kpts=np.int32(multi_key_points[index])

#nose->left_eye->left_ear.(0,1),(1,3)
cv.line(src,(kpts[0][0],kpts[0][1]),(kpts[1][0],kpts[1][1]),(255,255,0),2,8,0)
cv.line(src,(kpts[1][0],kpts[1][1]),(kpts[3][0],kpts[3][1]),(255,255,0),2,8,0)
#nose->right_eye->right_ear.(0,2),(2,4)
cv.line(src,(kpts[0][0],kpts[0][1]),(kpts[2][0],kpts[2][1]),(255,255,0),2,8,0)
cv.line(src,(kpts[2][0],kpts[2][1]),(kpts[4][0],kpts[4][1]),(255,255,0),2,8,0)
#nose->left_shoulder->left_elbow->left_wrist.(0,5),(5,7),(7,9)
cv.line(src,(kpts[0][0],kpts[0][1]),(kpts[5][0],kpts[5][1]),(255,255,0),2,8,0)
cv.line(src,(kpts[5][0],kpts[5][1]),(kpts[7][0],kpts[7][1]),(255,255,0),2,8,0)
cv.line(src,(kpts[7][0],kpts[7][1]),(kpts[9][0],kpts[9][1]),(255,255,0),2,8,0)
#nose->right_shoulder->right_elbow->right_wrist.(0,6),(6,8),(8,10)
cv.line(src,(kpts[0][0],kpts[0][1]),(kpts[6][0],kpts[6][1]),(255,255,0),2,8,0)
cv.line(src,(kpts[6][0],kpts[6][1]),(kpts[8][0],kpts[8][1]),(255,255,0),2,8,0)
cv.line(src,(kpts[8][0],kpts[8][1]),(kpts[10][0],kpts[10][1]),(255,255,0),2,8,0)
#left_shoulder->left_hip->left_knee->left_ankle.(5,11),(11,13),(13,15)
cv.line(src,(kpts[5][0],kpts[5][1]),(kpts[11][0],kpts[11][1]),(255,255,0),2,8,0)
cv.line(src,(kpts[11][0],kpts[11][1]),(kpts[13][0],kpts[13][1]),(255,255,0),2,8,0)
cv.line(src,(kpts[13][0],kpts[13][1]),(kpts[15][0],kpts[15][1]),(255,255,0),2,8,0)
#right_shoulder->right_hip->right_knee->right_ankle.(6,12),(12,14),(14,16)
cv.line(src,(kpts[6][0],kpts[6][1]),(kpts[12][0],kpts[12][1]),(255,255,0),2,8,0)
cv.line(src,(kpts[12][0],kpts[12][1]),(kpts[14][0],kpts[14][1]),(255,255,0),2,8,0)
cv.line(src,(kpts[14][0],kpts[14][1]),(kpts[16][0],kpts[16][1]),(255,255,0),2,8,0)
forx,y,_,inkpts:
cv.circle(src,(int(x),int(y)),3,(0,0,255),2,8,0)

index+=1
cv.imshow("KeyPointRCNNDetectionDemo",src)
cv.waitKey(0)
cv.destroyAllWindows()
测试与运行结果如下:

39f23f08-4b9d-11ed-a3b6-dac502259ad0.jpg

3a16916e-4b9d-11ed-a3b6-dac502259ad0.jpg

基于3050的卡,GPU推理,速度!没办法模型有点大,速度有点慢,需要好N卡加持才能实时检测!

3a53ac7a-4b9d-11ed-a3b6-dac502259ad0.png







审核编辑:刘清

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 编解码
    +关注

    关注

    1

    文章

    149

    浏览量

    20442
  • python
    +关注

    关注

    57

    文章

    4858

    浏览量

    89600
  • CAF
    CAF
    +关注

    关注

    1

    文章

    20

    浏览量

    14841

原文标题:姿态评估之使用KeyPointRCNN关键点检测模型轻松搞定!

文章出处:【微信号:CVSCHOOL,微信公众号:OpenCV学堂】欢迎添加关注!文章转载请注明出处。

收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    技术实践:利用房天下 API 按关键获取房产数据列表

    市场分析的开发者非常有用。 一、 接口概述 房天下平台为其合作伙伴或注册开发者提供了数据接口服务,允许通过 HTTP 请求获取其数据库中的房产信息。其中,根据关键词搜索房源列表是一常用且核心的功能。 核心功能: 输入一
    的头像 发表于 11-21 14:01 110次阅读
    技术实践:利用房天下 API 按<b class='flag-5'>关键</b>词<b class='flag-5'>获取</b>房产数据列表

    【EASY EAI Nano-TB(RV1126B)开发板试用】AI手部21关键识别

    【前言】 在前面的几篇帖子中,我处理好了桌面显示,驱动了摄像头。本篇将摄像头获取到的图像,通过AI来识别手部21关键的识别。 【步骤】 1、安装mediapipe 这次灵眸官网给出
    发表于 11-21 11:31

    顺企网平台根据关键获取企业列表API接口详解与实现

    ​  在企业信息查询、市场调研或商业智能应用中,获取精准的企业列表数据至关重要。顺企网作为国内知名的企业信息平台,提供了丰富的企业数据服务。本文将重点介绍其提供的“根据关键获取企业列表”API接口
    的头像 发表于 11-20 14:14 90次阅读
    顺企网平台根据<b class='flag-5'>关键</b>词<b class='flag-5'>获取</b>企业列表API接口详解与实现

    爱回收平台根据关键获取品牌ID的API接口详解

    ​  爱回收平台(Aihuishou)是一专注于二手电子产品回收的服务平台,提供了丰富的API接口以支持开发者集成其功能。其中,“根据关键获取品牌ID”的API是一常用接口,允许
    的头像 发表于 11-19 14:42 181次阅读
    爱回收平台根据<b class='flag-5'>关键</b>词<b class='flag-5'>获取</b>品牌ID的API接口详解

    小红书获取笔记正文和赞数的API接口

    ​  小红书(RED)是一流行的社交平台,用户分享笔记(类似博客文章)。开发者和数据分析师常需要通过API接口获取笔记正文和赞数,用于内容分析或应用开发。本文将详细介绍如何实现这一功能,包括
    的头像 发表于 11-18 16:27 624次阅读
    小红书<b class='flag-5'>获取</b>笔记正文和<b class='flag-5'>点</b>赞数的API接口

    拼多多搜索关键获取商品信息的API接口

    ​ 在现代电商开发中,API接口是获取平台数据的关键工具。拼多多作为主流电商平台,提供了丰富的API接口,允许开发者通过关键词搜索获取商品信息。本文将逐步介绍如何实现这一过程,确保内容
    的头像 发表于 11-10 15:29 146次阅读
    拼多多搜索<b class='flag-5'>关键</b>词<b class='flag-5'>获取</b>商品信息的API接口

    微店API秘籍!轻松获取商品详情数据

    一、前言 微店商品详情API是微店开放平台提供的核心接口之一,支持通过商品ID获取商品的完整信息,包括标题、价格、库存、图片等关键数据。该接口广泛应用于电商系统开发、数据分析和供应链管理场景,相比
    的头像 发表于 11-05 10:30 271次阅读

    搜索关键获取商品详情接口的设计与实现

    ​   在电商、内容平台等应用中,用户经常通过输入关键词搜索商品并获取详情。设计一高效、可靠的API接口是核心需求。本文将逐步介绍如何设计并实现一“搜索
    的头像 发表于 10-20 15:37 310次阅读
    搜索<b class='flag-5'>关键</b>词<b class='flag-5'>获取</b>商品详情接口的设计与实现

    材料的晶体结构看不清?EBSD助您获取关键数据

    关键信息1.物相鉴定:EBSD能够对每个分析进行物相的识别和确认,这一过程基于晶体学的差异,并可结合化学信息(如能谱仪EDS提供的数据)。2.晶体取向:EBSD
    的头像 发表于 09-30 15:38 703次阅读
    材料的晶体结构看不清?EBSD助您<b class='flag-5'>获取</b><b class='flag-5'>关键</b>数据

    瑞芯微RK3576人体关键识别算法(骨骼

    人体关键识别是一种基于深度学习的对人进行检测定位与姿势估计的模型,广泛应用于体育分析、动物行为监测和机器人等领域,帮助机器实时解读物理动作。本算法具有运行效率高、实时性强的特点。
    的头像 发表于 08-27 10:07 854次阅读
    瑞芯微RK3576<b class='flag-5'>人体</b><b class='flag-5'>关键</b><b class='flag-5'>点</b>识别算法(骨骼<b class='flag-5'>点</b>)

    【开发实例】基于BPI-CanMV-K230D-Zero开发板实现人体关键的实时动态识别

    项目介绍人体关键点检测应用使用YOLOv8n-pose模型对人体姿态进行检测;检测结果得到17个人体骨骼
    的头像 发表于 07-08 08:04 1027次阅读
    【开发实例】基于BPI-CanMV-K230D-Zero开发板实现<b class='flag-5'>人体</b><b class='flag-5'>关键</b><b class='flag-5'>点</b>的实时动态识别

    【BPI-CanMV-K230D-Zero开发板体验】人体关键点检测

    关键点检测应用使用 YOLOv8n-pose 模型对人体姿态进行检测; 检测结果得到 17人体骨骼关键
    发表于 06-28 13:18

    学会这些方法,轻松搞定SMT贴片加工的坐标获取与校正

    一站式PCBA加工厂家今天为大家讲讲SMT贴片加工中如何获取坐标与校正?SMT贴片加工中的坐标获取与校正方法。在SMT贴片加工过程中,精准的坐标获取与校正是确保组件精准放置、提高产品质量的关键
    的头像 发表于 05-29 10:27 625次阅读

    SiC MOSFET驱动电路设计的关键

    栅极驱动器是确保SiC MOSFET安全运行的关键,设计栅极驱动电路的关键包括栅极电阻、栅极电压和布线方式等,本章节带你了解栅极驱动电压的影响以及驱动电源的要求。
    的头像 发表于 05-06 15:54 1317次阅读
    SiC MOSFET驱动电路设计的<b class='flag-5'>关键</b><b class='flag-5'>点</b>

    选购红外热像仪的12关键

    红外热像仪作为现代工业和科技领域不可或缺的工具,其应用范围日益广泛。然而,面对市场上众多品牌和型号,如何选购一款既符合预算又满足需求的红外热像仪呢?小菲将为你详细解析选购红外热像仪的12关键,助你精准投资!
    的头像 发表于 04-10 14:13 786次阅读