tensorflow官方posenet模型解析

前言

tensorflow官方有个姿态估计项目,这个输入和openpose还有点不一样,这里写个单人情况下的模型输出解析方案。

国际惯例,参考博客:

博客: 使用 TensorFlow.js 在浏览器端上实现实时人体姿势检测

tensorflow中posnet的IOS代码

解析

不要下载官方overview网址下的posenet模型multi_person_mobilenet_v1_075_float.tflite,要去下载IOS端的posenet_mobilenet_v1_100_257x257_multi_kpt_stripped.tflite模型,在github上一搜有一堆,文末放网盘下载地址。

读取模型

先载入必要的工具包:

import numpy as np
import tensorflow as tf
import cv2 as cv
import matplotlib.pyplot as plt
import time

使用tflite载入模型文件

model = tf.lite.Interpreter('posenet_mobilenet_v1_100_257x257_multi_kpt_stripped.tflite')
model.allocate_tensors()
input_details = model.get_input_details()
output_details = model.get_output_details()

看看输入输出分别是什么

print(input_details)
print(output_details)
'''
[{'name': 'sub_2', 'index': 93, 'shape': array([  1, 257, 257,   3], dtype=int32), 'dtype': <class 'numpy.float32'>, 'quantization': (0.0, 0)}]
[{'name': 'MobilenetV1/heatmap_2/BiasAdd', 'index': 87, 'shape': array([ 1,  9,  9, 17], dtype=int32), 'dtype': <class 'numpy.float32'>, 'quantization': (0.0, 0)}, {'name': 'MobilenetV1/offset_2/BiasAdd', 'index': 90, 'shape': array([ 1,  9,  9, 34], dtype=int32), 'dtype': <class 'numpy.float32'>, 'quantization': (0.0, 0)}, {'name': 'MobilenetV1/displacement_fwd_2/BiasAdd', 'index': 84, 'shape': array([ 1,  9,  9, 32], dtype=int32), 'dtype': <class 'numpy.float32'>, 'quantization': (0.0, 0)}, {'name': 'MobilenetV1/displacement_bwd_2/BiasAdd', 'index': 81, 'shape': array([ 1,  9,  9, 32], dtype=int32), 'dtype': <class 'numpy.float32'>, 'quantization': (0.0, 0)}]
'''

很容易看出输入是(257,257)尺寸的彩色图像。

输出就比较麻烦了,有两块:(9,9,17)的称为heatmap的热度图;(9,9,34)的称为offset的偏移图。其实想想也能知道,热度图定位关节的大概位置,用偏移图做进一步的矫正。接下来逐步分析怎么利用这两个输出将关节位置定位的。

输入图像推断

必须将图像resize一下再丢进去,但是tensorflowjs里面说不用resize的方法,我还没试过。

img = cv.imread('../../photo/1.jpeg')
input_img = tf.reshape(tf.image.resize(img, [257,257]), [1,257,257,3])
floating_model = input_details[0]['dtype'] == np.float32
if floating_model:input_img = (np.float32(input_img) - 127.5) / 127.5
model.set_tensor(input_details[0]['index'], input_img)
start = time.time()
model.invoke()
print('time:',time.time()-start)
output_data =  model.get_tensor(output_details[0]['index'])
offset_data = model.get_tensor(output_details[1]['index'])
heatmaps = np.squeeze(output_data)
offsets = np.squeeze(offset_data)
print("output shape: {}".format(output_data.shape))
'''
time: 0.12212681770324707
output shape: (1, 9, 9, 17)
'''

可视化变换后的图

show_img = np.squeeze((input_img.copy()*127.5+127.5)/255.0)[:,:,::-1]
show_img = np.array(show_img*255,np.uint8)
plt.imshow(show_img)
plt.axis('off')

在这里插入图片描述

解析输出

一句话概括原理:热度图将图像划分网格,每个网格的得分代表当前关节在此网格点附近的概率;偏移图代表xy两个坐标相对于网格点的偏移情况。

假设提取第2个关节的坐标位置:

  • 先得到最可能的网格点:

    i=1
    joint_heatmap = heatmaps[...,i]
    max_val_pos = np.squeeze(np.argwhere(joint_heatmap==np.max(joint_heatmap)))
    remap_pos = np.array(max_val_pos/8*257,dtype=np.int32)
    
  • offset加上去,前1-17是x坐标偏移,后18-34是y坐标偏移

    refine_pos = np.zeros((2),dtype=int)
    refine_pos[0] = int(remap_pos[0] + offsets[max_val_pos[0],max_val_pos[1],i])
    refine_pos[1] = int(remap_pos[1] + offsets[max_val_pos[0],max_val_pos[1],i+heatmaps.shape[-1]])
    

可视化看看

show_img = np.squeeze((input_img.copy()*127.5+127.5)/255.0)[:,:,::-1]
show_img = np.array(show_img*255,np.uint8)
plt.figure(figsize=(8,8))
plt.imshow(cv.circle(show_img,(refine_pos[1],refine_pos[0]),2,(0,255,0),-1))

在这里插入图片描述

映射原图

因为上面是把原图resize乘(257,257)以后的坐标,所以根据原图的缩放系数,重新映射回去

ratio_x = img.shape[0]/257
ratio_y = img.shape[1]/257
refine_pos[0]=refine_pos[0]*ratio_x
refine_pos[1]=refine_pos[1]*ratio_y

可视化

show_img1 = img[:,:,::-1]
plt.figure(figsize=(8,8))
plt.imshow(cv.circle(show_img1.copy(),(refine_pos[1],refine_pos[0]),2,(0,255,0),-1))

在这里插入图片描述

封装函数

上面是提取单个关节的,写成函数提取所有关节的坐标就是

def parse_output(heatmap_data,offset_data):joint_num = heatmap_data.shape[-1]pose_kps = np.zeros((joint_num,2),np.uint8)for i in range(heatmap_data.shape[-1]):joint_heatmap = heatmap_data[...,i]max_val_pos = np.squeeze(np.argwhere(joint_heatmap==np.max(joint_heatmap)))remap_pos = np.array(max_val_pos/8*257,dtype=np.int32)pose_kps[i,0] = int(remap_pos[0] + offset_data[max_val_pos[0],max_val_pos[1],i])pose_kps[i,1] = int(remap_pos[1] + offset_data[max_val_pos[0],max_val_pos[1],i+joint_num])return pose_kps

画图的函数也很容易

def draw_kps(show_img,kps):for i in range(kps.shape[0]):cv.circle(show_img,(kps[i,1],kps[i,0]),2,(0,255,0),-1)return show_img

画出来瞅瞅

kps = parse_output(heatmaps,offsets)
plt.figure(figsize=(8,8))
plt.imshow(draw_kps(show_img.copy(),kps))
plt.axis('off')

在这里插入图片描述

后记

模型文件:链接:https://pan.baidu.com/s/1heRKFFz28yvpAmvFqDeAXw 密码:5tuw

博客代码:链接:https://pan.baidu.com/s/1Y7WXfQ4WC9QyOGkkN2-kUQ 密码:ono0

本文已经同步到微信公众号中,公众号与本博客将持续同步更新运动捕捉、机器学习、深度学习、计算机视觉算法,敬请关注
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

tensorflow2安装时候的一个dll找不到的错误

电脑环境&#xff1a; vs2015python3.7.6&#xff0c;使用anaconda安装的CUDA 10.1cuDnn 7.6.5tensorflow2.1.0 错误内容 File "C:\Users\zb116\anaconda3\lib\imp.py", line 242, in load_modulereturn load_dynamic(name, filename, file)File "C:\Users\z…

PCA、SVD、ZCA白化理论与实现

简介 在UFLDL中介绍了主成分分析这一块的知识&#xff0c;而且当时学机器学习的时候&#xff0c;老师是将PCA和SVD联系起来将的&#xff0c;同时UFLDL也讲到了使用PCA做数据白化whitening处理&#xff0c;这个词经常在论文里面看到。 国际惯例&#xff0c;参考博客&#xff1…

OpenCV使用Tensorflow2-Keras模型

前言 最近工作上需要在C上快速集成Tensorflow/Keras训练好的模型&#xff0c;做算法验证。首先想到的就是opencv里面的dnn模块了&#xff0c;但是它需要的格式文件比较郁闷&#xff0c;是pb格式的模型&#xff0c;但是keras通常保存的是h5文件&#xff0c;查阅了很多资料&…

3D人脸表情驱动——基于eos库

前言 之前出过三篇换脸的博文&#xff0c;遇到一个问题是表情那一块不好处理&#xff0c;可行方法是直接基于2D人脸关键点做网格变形&#xff0c;强行将表情矫正到目标人脸&#xff0c;还有就是使用PRNet的思想&#xff0c;使用目标人脸的顶点模型配合源人脸的纹理&#xff0c…

3D姿态估计——ThreeDPose项目简单易用的模型解析

前言 之前写过tensorflow官方的posenet模型解析&#xff0c;用起来比较简单&#xff0c;但是缺点是只有2D关键点&#xff0c;本着易用性的原则&#xff0c;当然要再来个简单易用的3D姿态估计。偶然看见了ThreeDPose的项目&#xff0c;感觉很强大的&#xff0c;所以把模型扒下来…

简易的素描图片转换流程与实现

前言 之前经常在网上看到用PS实现真实图片到素描图片的转换&#xff0c;但是流程都大同小异&#xff0c;身为一只程序猿&#xff0c;必须来个一键转化额。 国际惯例&#xff0c;参考博客&#xff1a; Photoshop基础教程&#xff1a;混合模式原理篇 颜色减淡的原理讲解以及应…

一个简单好用的磨皮祛斑算法理论和python实现

前言 最近看了一个磨皮算法祛斑感觉效果不错&#xff0c;效果图看文末就行&#xff0c;个人觉得效果非常不错滴。 国际惯例&#xff0c;参考博客&#xff1a; 磨皮算法的源码&#xff1a;YUCIHighPassSkinSmoothing How To Smooth And Soften Skin With Photoshop 图像算法…

OpenVINO——配置与道路分割案例

前言 最近看到了一个深度学习库OpenVINO&#xff0c;专门用于Intel硬件上部署深度学习模型&#xff0c;其内置了非常非常多使用的预训练模型&#xff0c;比如道路分割、人脸提取、3D姿态估计等等。但是配置和调用有点小恶心&#xff0c;这里以道路分割为例&#xff0c;展示如何…

图像颜色迁移《color transfer between images》

前言 前段时间&#xff0c;在深度学习领域不是有个比较火的方向叫风格迁移的嘛&#xff0c;对于我这种不喜欢深度学习那种不稳定结果的人来说&#xff0c;还是想看看传统图像处理领域有什么类似的技术&#xff0c;发现了一个颜色迁移的算法&#xff0c;很久前的论文了。 国际…

ColorSpace颜色空间简介

前言 如果看过之前的介绍的图像颜色迁移《color transfer between images》和颜色协调模型Color Harmoniztion就会发现&#xff0c;大部分图像处理算法虽然输入输出是RGB像素值&#xff0c;但是中间进行算法处理时很少直接更改RGB值&#xff0c;而是转换到其它空间&#xff0c…

Ogre共享骨骼与两种骨骼驱动方法

前言 最近业务中用到Ogre做基于3D关键点虚拟角色骨骼驱动&#xff0c;但是遇到两个问题&#xff1a; 身体、头、眼睛、衣服等mesh的骨骼是分开的&#xff0c;但是骨骼结构都是一样的&#xff0c;需要设置共享骨骼驱动的时候可以直接修改骨骼旋转量&#xff0c;或者将旋转量存…

仿射变换和透视变换

前言 在前面做换脸的博客中提到了使用仿射变换和透视变换将两张不同的人脸基于关键点进行对齐&#xff0c;保证一张人脸贴到另一张人脸时&#xff0c;大小完全一致&#xff1b;所以有必要理解一下这两个概念的区别&#xff0c;由于以实用性为目的&#xff0c;所以所有的图像算…

obj格式解析

前言 最近处理一些网格渲染的时候&#xff0c;需要解析Obj文件&#xff0c;从Free3D上随便找了个免费的人体obj模型解析测试一波 国际惯例&#xff0c;参考博客&#xff1a; 本文所使用的从Free3D下载的模型 .obj文件格式与.mtl文件格式 详解3D中的obj文件格式 3D中OBJ文…

Flask服务部署与简单内网穿透

前言 最近学习部署的时候&#xff0c;想到深度学习里面通常用的部署方法是flask做服务端&#xff0c;然后使用nginx做负载均衡&#xff0c;貌似也能做内网穿透。不过我不太懂负载均衡&#xff0c;只想利用本地电脑搭建一个简单的服务器&#xff0c;实现外部调用API服务的功能。…

OpenCV学习——轮廓检测

前言 轮廓检测是传统视觉中非常常用的功能&#xff0c;这里简单记录一下opencv中的轮廓检测算法使用方法&#xff0c;至于理论&#xff0c;后续有机会再去细品。 国际惯例&#xff1a; OpenCV官方的轮廓检测教程python版 OpenCV中的二值化方法教程 OpenCV轮廓层级官方文档…

RBF神经网络理论与实现

前言 最近发现有挺多人喜欢径向基函数(Radial Basis Function,RBF)神经网络&#xff0c;其实它就是将RBF作为神经网络层间的一种连接方式而已。这里做一个简单的描述和找了个代码解读。 之前也写过一篇&#xff0c;不过排版不好看&#xff0c;可以戳这里跳转 国际惯例&#x…

基于python和unity交互的卡通角色肢体和表情驱动(深度学习)

前言 最近看到了好多卡通角色的肢体驱动的东东&#xff0c;感觉是时候发挥一下读研时候学的东西了&#xff0c;而且虽然现在不炼丹了&#xff0c;但是还是得保持吃丹的技能。这个项目找了很多很多代码进行测试&#xff0c;最终集成了一个3D姿态估计和人脸关键点提取的代码。 …

OpenCV学习——形态学

前言 继续学习图像里面的形态学知识——结构元、腐蚀、膨胀、开运算、闭运算、击中/不击中变换。以及部分基本形态学算法&#xff0c;包括边界提取、空洞填充、连通分量的提取、凸壳、细化、粗化、骨架、裁剪、形态学重建。 其实就是对冈萨雷斯的《数字图像处理》中第9章节《…

径向基函数RBF三维网格变形

前言 之前写过径向基函数(RBF)神经网络做分类或者拟合。然后挖了个坑说在《Phase-Functioned Neural Networks for Character Control》里面提到了用于做地形编辑&#xff0c;所以这篇博客就是解析一下如何用RBF做网格编辑系统。 参考博客&#xff1a; Noe’s tutorial on d…

OBJ可视化——UV还原(修正)

前言 前面写过一篇obj格式解析的博客&#xff0c;但是这篇文章中可视化的工作是参考PRNet的源码进行的&#xff0c;后来细细思考了一下&#xff0c;有点问题&#xff0c;具体看下面。 问题来源 在PRNet源码的render.py中有个函数render_texture&#xff0c;是作者用于将uv展…