当前位置: 首页 > news >正文

实战——OPenPose讲解及代码实现

一些前提

先思考下面几个问题;

1、什么是姿态估计?

参考:Point Detect任务,识别人体指定部分的关键点;

2、姿态估计中的难点是什么?

从干扰的角度,人体被遮挡对检测的影响很大;

如何对检测的点进行匹配拼接,并且是顺序拼接,而且确保是同一个人;

怎么提升性能,算法能够实时推理;

3、COCO数据集的关键点有几个,分别是?

在这里插入图片描述

数据集中是17个点,实际上训练时候还要加上一个脖子的点,通过两个肩膀的点计算;

4、应用领域有哪些?

  • 运动领域:例如健身动作识别;
  • 安全领域:路面防摔跤、游泳池溺水;
  • 特殊需求:比如是否佩戴某件物品,可以根据关键点和物体的定位;

5、姿态估计方法分为几个大类?

  • Top-down(自顶向下):先检测所有的人,再对每个框的人进行姿态估计输出结果

    优点:准确率高,点的回归率高;

    缺点:算法性能依赖检测效果,复杂度较高,实时性比较差;

    主要用于一些离线的项目,对实时性没要求!!!

  • bottom-up(自底向上):先检测所有关键点,再进行匹配连接

    优点:计算量较小,可以达到实时性的效果;

    缺点:精度较差,匹配策略比较复杂;

论文解读

论文地址:https://arxiv.org/pdf/1611.08050.pdf

参考文章:https://zhuanlan.zhihu.com/p/514078285

首先看一下整体的流程图:

在这里插入图片描述

首先输入一张W * H的图像进入网络,网络会有两个分支:

一是关键点检测,会生成一个热力图,检测出J个标签部位的点;

二是得到关键点的方向关系,也被称为PAF,对于每一个关键点都有其亲和域的方向;

最终结合二者,将所有关键点连接起来,输出一个完整的人体骨架;

算法流程

重点的关注点:

1、关键点的heatmap标注生成,采用高斯函数;

2、PAF:部分亲和域,文章提出的重要方法;

3、匹配策略:匈牙利匹配;

1、数据制作

采用的数据集为COCO数据集,其中人体骨骼点的标注信息为【x,y,label】,这里的label取值为0、1、2,分别表示不存在、遮挡、正常,其中不存在的关键点是需要去除的;

关键点高斯热力图实现:

def putGaussianMaps(center, accumulate_confid_map, sigma, grid_y, grid_x, stride):start = stride / 2.0 - 0.5y_range = [i for i in range(int(grid_y))]x_range = [i for i in range(int(grid_x))]xx, yy = np.meshgrid(x_range, y_range)      # 构建棋盘xx = xx * stride + start                    # 每个点在原始图像上的位置yy = yy * stride + startd2 = (xx - center[0]) ** 2 + (yy - center[1]) ** 2  # 计算每个点和GT点的距离exponent = d2 / 2.0 / sigma / sigma                 # 这里在做一个高斯计算mask = exponent <= 4.6052                           # 将在这个阈值范围内的点用True记录cofid_map = np.exp(-exponent)                       # 这里做一个标准化cofid_map = np.multiply(mask, cofid_map)            # 取出对应关系为True的点accumulate_confid_map += cofid_map                  # 将每个点计算的结果都累加到上一次的特征中accumulate_confid_map[accumulate_confid_map > 1.0] = 1.0      # 对结果大于1的值,只取1return accumulate_confid_map    # 返回热力图(heatmap)

PAF数据计算的实现:

def putVecMaps(centerA, centerB, accumulate_vec_map, count, grid_y, grid_x, stride):centerA = centerA.astype(float)centerB = centerB.astype(float)thre = 1  # 表示宽度,也就是一个设定好的参数centerB = centerB / stride  # 缩放比例特定到特征图中centerA = centerA / stridelimb_vec = centerB - centerA  # 求出两个点的向量norm = np.linalg.norm(limb_vec)  # 是需要求单位向量,所以先计算范数,也就是向量模长if (norm == 0.0):  # 这里表示两个点基本重合了# print 'limb is too short, ignore it...'return accumulate_vec_map, countlimb_vec_unit = limb_vec / norm  # 向量除以模长,得到单位向量# print 'limb unit vector: {}'.format(limb_vec_unit)# To make sure not beyond the border of this two points# 得到所有可能存在方向的区域(这里就用到了之前的超参数阈值)min_x = max(int(round(min(centerA[0], centerB[0]) - thre)), 0)max_x = min(int(round(max(centerA[0], centerB[0]) + thre)), grid_x)min_y = max(int(round(min(centerA[1], centerB[1]) - thre)), 0)max_y = min(int(round(max(centerA[1], centerB[1]) + thre)), grid_y)# 得到一个可能存在向量的矩形框range_x = list(range(int(min_x), int(max_x), 1))range_y = list(range(int(min_y), int(max_y), 1))xx, yy = np.meshgrid(range_x, range_y)  # 制作一个网格ba_x = xx - centerA[0]  # the vector from (x,y) to centerA 根据位置判断是否在该区域上(分别得到X和Y方向的)ba_y = yy - centerA[1]# 向量叉乘根据阈值选择赋值区域,任何向量与单位向量的叉乘即为四边形的面积# 这里是重点步骤,也就是论文中的公式,表示计算出两个向量组成四边形的面积limb_width = np.abs(ba_x * limb_vec_unit[1] - ba_y * limb_vec_unit[0])mask = limb_width < thre  # mask is 2D (小于阈值的表示在该区域上)vec_map = np.copy(accumulate_vec_map) * 0.0  # 构建一个全为0的矩阵# 这行代码主要作用是将mask扩展一个维度并且赋值给vec_map数组vec_map[yy, xx] = np.repeat(mask[:, :, np.newaxis], 2, axis=2)# 在该区域上的都用对应的方向向量表示(根据mask结果表示是否在,通过乘法的方式)vec_map[yy, xx] *= limb_vec_unit[np.newaxis, np.newaxis, :]# #在特征图中(46*46)中 哪些区域是该躯干所在区域,判断x或者y向量都不为0mask = np.logical_or.reduce((np.abs(vec_map[:, :, 0]) > 0, np.abs(vec_map[:, :, 1]) > 0))# 每次返回的accumulate_vec_map都是平均值,现在还原成实际值accumulate_vec_map = np.multiply(accumulate_vec_map, count[:, :, np.newaxis])accumulate_vec_map += vec_map  # 加上当前关键点位置形成的向量count[mask == True] += 1  # 该区域计算次数都+1mask = count == 0count[mask == True] = 1  # 没有被计算过的地方就等于自身(因为一会要除法)accumulate_vec_map = np.divide(accumulate_vec_map, count[:, :, np.newaxis])  # 算平均向量count[mask == True] = 0  # 还原回去return accumulate_vec_map, count

这两个函数是最重要的两个部分,也就是对训练数据的处理,生成出需要的训练数据,其中遍历原始数据的代码并没有展示,详细可以看看源代码中的data.py文件;

2、模型搭建

下面看一下总的网络架构:

在这里插入图片描述

模型的backbone可以选择比较多,这里选择VGG19,在Stage1之前得到一个46x46大小的特征图;

接下来通过几个stage不断地·扩大感受野,提升模型的效果,每次上面结构输出关键点的热力图(维度为19),下面结果输出关键点的PAF方向信息(维度为38),计算损失保存,接下来将两个维度的特征进行拼接,再传入接下来的stage中,通过不断的堆叠提升整个算法的精度;

3、预测推理

预测模型这里,在官方源码中是将paf的处理封装在一个cpp库中,通过编译得到静态库,代码中可以调用;

这里PAF的处理主要是采用积分计算的方式,也就是对于连线的点的方向选择,采用积分的方式计算最佳连线策略;

运行picture_demo.py得到最终的结果,如下图所示:

模型结果及推理耗时:

可以看出模型的结构为Vgg19,这是可以替换的,并且特征图的输出维度为38和19,这也符合定义的骨骼点分类和连接方式;

总结

一些细节例如匈牙利匹配算法、PAF权值计算、模型结构改进等在这里并没有过多介绍;

并且对于现在OPenpoe的使用,主要是将其编译成一个库,作为Python程序的调用;

并且相比于本次的代码,其实时性很好,符合大部分落地场景的需求;

如果有想要本次项目源码的,可以在评论区留下邮箱,也欢迎大家一起讨论,后续也会探讨更多最新的技术;

相关文章:

实战——OPenPose讲解及代码实现

一些前提 先思考下面几个问题&#xff1b; 1、什么是姿态估计&#xff1f; 参考&#xff1a;Point Detect任务&#xff0c;识别人体指定部分的关键点&#xff1b; 2、姿态估计中的难点是什么&#xff1f; 从干扰的角度&#xff0c;人体被遮挡对检测的影响很大&#xff1b;…...

专注于创意设计,为您的小程序和网站建设带来更多的可能性

随着移动互联网的快速发展&#xff0c;越来越多的企业开始关注小程序和网站建设&#xff0c;以此来拓展业务和提升品牌形象。 在这个领域中&#xff0c;创意设计扮演着关键的角色。它不仅可以帮助企业打造独特的形象和品牌&#xff0c;还能够提高用户体验和购买决策的效率。 因…...

ATF(TF-A)安全通告 TFV-6 (CVE-2017-5753, CVE-2017-5715, CVE-2017-5754)

ATF(TF-A)安全通告汇总 目录 一、ATF(TF-A)安全通告 TFV-6 (CVE-2017-5753, CVE-2017-5715, CVE-2017-5754) 二、Variant 1 (CVE-2017-5753) 三、Variant 2 (CVE-2017-5715) 四、Variant 3 (CVE-2017-5754) 一、ATF(TF-A)安全通告 TFV-6 (CVE-2017-5753, CVE-2017-5715, C…...

vue3 基础语法 02

你好&#xff0c;今天过的怎么样呀&#xff0c;嘿嘿&#xff0c;加油夏 &#x1f495; 文章目录 一、模板语法 一、模板语法 React的开发模式&#xff1a; React 使用的 jsx&#xff0c;对应的代码编写的类似于js的一种语法&#xff1b;通过 Babel 将 jsx &#xff0c; 编译成…...

版本控制工具——git

版本控制是指对软件开发过程中各种程序代码、配置文件及说明文档等文件变更的管理&#xff0c;是软件配置管理的核心思想之一。 版本控制最主要的功能就是追踪文件的变更。它将什么时候、什么人更改了文件的什么内容等信息忠实地了记录下来。每一次文件的改变&#xff0c;文件的…...

超详细,自动化测试实战-获取配置文件信息(实例源码)

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 配置文件的类型 …...

spring 2.7.14 cors 设置 allowedOrigins(“*“)通配符 失效怎么解决

失效代码&#xff1a; package com.yukuanyan.searcher_web.config;import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.CorsRegistry; import org.springframework.web.servlet.config.annotation.WebM…...

一、Go的前景与优势、基础语法

Go简介 Go的公司、场景应用 公司占比&#xff1a; 字节跳动领先&#xff0c;公司内部有上万个微服务使用go来编写&#xff0c;不久前也开源了GO RPC框架KiteX。 同时&#xff0c;腾讯、百度、美团、滴滴、深信服、平安、OPPO、知乎、去哪儿、360、金山、微博、哩哔哩、七牛、…...

shell脚本循环语句

shell脚本循环语句 一.echo命令二.查看当前系统的时间--date命令三.循环语句for四.while循环语句结构五.while循环语句结构&#xff08;迭代&#xff09;六.continue和break 一.echo命令 echo -n 表示不换行输出 echo -e输出转义符&#xff0c;将转义后的内容输出到屏幕上 常…...

二叉树题目:二叉树的直径

文章目录 题目标题和出处难度题目描述要求示例数据范围 解法思路和算法代码复杂度分析 题目 标题和出处 标题&#xff1a;二叉树的直径 出处&#xff1a;543. 二叉树的直径 难度 3 级 题目描述 要求 给定二叉树的根结点 root \texttt{root} root&#xff0c;返回其直径…...

嵌入式:C高级 Day4

一、整理思维导图 二、写一个函数&#xff0c;获取用户的uid和gid并使用变量接收 三、整理冒泡排序、简单选择排序和快速排序的代码 冒泡排序 #include <myhead.h>void output(int arr[], int len); void bubble_sort(int arr[], int len);int main(int argc, const ch…...

cmake常用命令(1)——函数相关

一、function/endfunction cmake中的函数与其他语言相似&#xff0c;表示一个命令集&#xff0c;可以被重复调用。形式如下&#xff1a; function(<name> [<arg1> ...])<commands> endfunction() function&#xff1a;表示函数开始 <name>&#xf…...

阿里三年功能测试的一些感悟

一、前言 功能测试是测试工程师的基础功&#xff0c;很多人功能测试还做不好&#xff0c;就想去做性能测试、自动化测试。很多人对功能测试的理解就是点点点&#xff0c;如何自己不用心去悟&#xff0c;去研究&#xff0c;那么你的职业生涯也就停留在点点点上了。在这里&#…...

React源码解析18(4)------ completeWork的工作流程【mount】

摘要 经过上一章&#xff0c;我们得到的FilberNode已经具有了child和return属性。一颗Filber树的结构已经展现出来了。 那我们最终是想在页面渲染真实的DOM。所以我们现在要在completeWork里&#xff0c;构建出一颗离屏的DOM树。 之前在说FilberNode的属性时&#xff0c;我们…...

Kafka: 详解、使用教程和示例

Kafka: 详细介绍、使用教程和示例 什么是 Kafka&#xff1f; Kafka 是一个分布式的流处理平台&#xff0c;最初由 LinkedIn 开发&#xff0c;现已成为 Apache 基金会的顶级项目。它以高吞吐量、可靠性和可扩展性而闻名&#xff0c;被广泛应用于实时数据传输、日志收集、事件处…...

【LeetCode周赛】LeetCode第358场周赛

LeetCode第358场周赛 数组中的最大数对和翻倍以链表形式表示的数字限制条件下元素之间的最小绝对差 数组中的最大数对和 给你一个下标从0开始的整数数组nums。请你从nums中找出和最大的一对数&#xff0c;且这两个数数位上最大的数字相等。 返回最大和&#xff0c;如果不存在满…...

Node.js学习笔记-04

这第九章也是个大重点 九、玩转进程 Node在选型时决定在V8引擎之上构建&#xff0c;也就意味着它的模型与浏览器类似。 本章关于进程的介绍和讨论将会解决如下两个问题&#xff1a; 单进程单线程并非完美&#xff0c;如今CPU基本均是多核的&#xff0c;真正的服务器&#xf…...

基于dbn+svr的交通流量预测,dbn详细原理

目录 背影 DBN神经网络的原理 DBN神经网络的定义 受限玻尔兹曼机(RBM) DBN+SVR的交通流量预测 基本结构 主要参数 数据 MATALB代码 结果图 展望 背影 DBN是一种深度学习神经网络,拥有提取特征,非监督学习的能力,是一种非常好的分类算法,本文将DBN+SVR用于交通流量预测…...

【第一阶段】kotlin中反引号中的函数名特点

在kotlin中可以直接中文定义函数&#xff0c;使用反引号进行调用 eg: fun main() {2023年8月9日定义的函数(5) }private fun 2023年8月9日定义的函数(num:Int){println("反引号的用法$num") }执行结果 在Java中is,in可以定义方法&#xff0c;但是在kotlin中is,in是…...

数据分析-python学习 (1)numpy相关

内容为&#xff1a;https://juejin.cn/book/7240731597035864121的学习笔记 导包 import numpy as np numpy数组创建 创建全0数组&#xff0c;正态分布、随机数组等就不说了&#xff0c;提供了相应的方法通过已有数据创建有两种 arr1np.array([1,2,3,4,5]) 或者datanp.loadt…...

论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(二)

HoST框架核心实现方法详解 - 论文深度解读(第二部分) 《Learning Humanoid Standing-up Control across Diverse Postures》 系列文章: 论文深度解读 + 算法与代码分析(二) 作者机构: 上海AI Lab, 上海交通大学, 香港大学, 浙江大学, 香港中文大学 论文主题: 人形机器人…...

中南大学无人机智能体的全面评估!BEDI:用于评估无人机上具身智能体的综合性基准测试

作者&#xff1a;Mingning Guo, Mengwei Wu, Jiarun He, Shaoxian Li, Haifeng Li, Chao Tao单位&#xff1a;中南大学地球科学与信息物理学院论文标题&#xff1a;BEDI: A Comprehensive Benchmark for Evaluating Embodied Agents on UAVs论文链接&#xff1a;https://arxiv.…...

uni-app学习笔记二十二---使用vite.config.js全局导入常用依赖

在前面的练习中&#xff0c;每个页面需要使用ref&#xff0c;onShow等生命周期钩子函数时都需要像下面这样导入 import {onMounted, ref} from "vue" 如果不想每个页面都导入&#xff0c;需要使用node.js命令npm安装unplugin-auto-import npm install unplugin-au…...

基于Uniapp开发HarmonyOS 5.0旅游应用技术实践

一、技术选型背景 1.跨平台优势 Uniapp采用Vue.js框架&#xff0c;支持"一次开发&#xff0c;多端部署"&#xff0c;可同步生成HarmonyOS、iOS、Android等多平台应用。 2.鸿蒙特性融合 HarmonyOS 5.0的分布式能力与原子化服务&#xff0c;为旅游应用带来&#xf…...

智能在线客服平台:数字化时代企业连接用户的 AI 中枢

随着互联网技术的飞速发展&#xff0c;消费者期望能够随时随地与企业进行交流。在线客服平台作为连接企业与客户的重要桥梁&#xff0c;不仅优化了客户体验&#xff0c;还提升了企业的服务效率和市场竞争力。本文将探讨在线客服平台的重要性、技术进展、实际应用&#xff0c;并…...

spring:实例工厂方法获取bean

spring处理使用静态工厂方法获取bean实例&#xff0c;也可以通过实例工厂方法获取bean实例。 实例工厂方法步骤如下&#xff1a; 定义实例工厂类&#xff08;Java代码&#xff09;&#xff0c;定义实例工厂&#xff08;xml&#xff09;&#xff0c;定义调用实例工厂&#xff…...

数据链路层的主要功能是什么

数据链路层&#xff08;OSI模型第2层&#xff09;的核心功能是在相邻网络节点&#xff08;如交换机、主机&#xff09;间提供可靠的数据帧传输服务&#xff0c;主要职责包括&#xff1a; &#x1f511; 核心功能详解&#xff1a; 帧封装与解封装 封装&#xff1a; 将网络层下发…...

Spring Boot面试题精选汇总

&#x1f91f;致敬读者 &#x1f7e9;感谢阅读&#x1f7e6;笑口常开&#x1f7ea;生日快乐⬛早点睡觉 &#x1f4d8;博主相关 &#x1f7e7;博主信息&#x1f7e8;博客首页&#x1f7eb;专栏推荐&#x1f7e5;活动信息 文章目录 Spring Boot面试题精选汇总⚙️ **一、核心概…...

【Web 进阶篇】优雅的接口设计:统一响应、全局异常处理与参数校验

系列回顾&#xff1a; 在上一篇中&#xff0c;我们成功地为应用集成了数据库&#xff0c;并使用 Spring Data JPA 实现了基本的 CRUD API。我们的应用现在能“记忆”数据了&#xff01;但是&#xff0c;如果你仔细审视那些 API&#xff0c;会发现它们还很“粗糙”&#xff1a;有…...

BCS 2025|百度副总裁陈洋:智能体在安全领域的应用实践

6月5日&#xff0c;2025全球数字经济大会数字安全主论坛暨北京网络安全大会在国家会议中心隆重开幕。百度副总裁陈洋受邀出席&#xff0c;并作《智能体在安全领域的应用实践》主题演讲&#xff0c;分享了在智能体在安全领域的突破性实践。他指出&#xff0c;百度通过将安全能力…...