python 人体检测技术_tensorflow入门教程(四十三)人体姿态检测(一)
#
#作者:韦访
#博客:https://blog.csdn.net/rookie_wei
#微信:1007895847
#添加微信的备注一下是CSDN的
#欢迎大家一起学习
#
------韦访 20190525
1、概述
这次我们先不讲原理,先在Github上拿个源码来跑,有感觉以后,再去分析它的工作原理和源码,所以这一讲我们先来个初探人体姿态检测。先来说说什么是人体姿态检测吧,
如上图所示,简单的说,就是检测出人体的双眼,鼻子,耳朵,双肩,双臂,臀部,膝盖等等关键点,然后再将这个关键点有序的连接起来,形成人的“骨架”。
2、源码下载
先把源码下载下来,下载完后,源码的大概结构如下图所示,
3、安装
一般看这种开源项目,先看看它的README文档说些什么,如果里面有安装使用说明,按照它的要求做就好了,来看这个项目的文档,
跟着做就好了,假设我们源码已经下载好了,cd到源码根目录了,然后执行,
sudo pip3 install -r requirements.txt
上面的命令就是通过pip安装一些需要的Python第三方库,
如果pycocotools库安装失败,则执行下面的命令安装,
sudo pip3 install git+https://github.com/philferriere/cocoapi.git#subdirectory=PythonAPI
接着,
cd tf_pose/pafprocess
swig -python -c++ pafprocess.i && python3 setup.py build_ext --inplace
然后去下载cmu模型的pb文件,
cd models/graph/cmu
bash download.sh
最后,电脑插上摄像头,在项目的根目录执行,
python run_webcam.py --model=mobilenet_thin --resize=432x368 --camera=0
运行结果如下,
我这渣渣摄像头总算又派上用场了~
4、run_webcam.py源码
我们来看一下run_webcam.py的源码,先找到main函数,
if __name__ == '__main__':
parser = argparse.ArgumentParser(description='tf-pose-estimation realtime webcam')
parser.add_argument('--camera', type=int, default=0)
parser.add_argument('--resize', type=str, default='0x0',
help='if provided, resize images before they are processed. default=0x0, Recommends : 432x368 or 656x368 or 1312x736 ')
parser.add_argument('--resize-out-ratio', type=float, default=4.0,
help='if provided, resize heatmaps before they are post-processed. default=1.0')
parser.add_argument('--model', type=str, default='mobilenet_thin', help='cmu / mobilenet_thin / mobilenet_v2_large / mobilenet_v2_small')
parser.add_argument('--show-process', type=bool, default=False,
help='for debug purpose, if enabled, speed for inference is dropped.')
args = parser.parse_args()
如上代码所示,一堆参数,我们大概看一下,camera参数,指定哪个摄像头,如果你是土豪的话,电脑有很多个摄像头,就可以指定使用哪个摄像头,只有一个的话就是0,resize参数,应该是调整要输出的图像的大小,resize-out-ratio参数,看它的help,resize heatmaps,我们先假装不知道这个heatmaps是什么东西,用它默认值就好了,model参数,这里有4个选项,应该是指定哪个模型,我们刚才不是下载了一个cmu的模型吗?这里就可以指定用cmu模型了,从命名可以看出,有三个模型都是以mobile命名的,应该是针对手机或者嵌入式设备的网络,那么就会比较在意资源的使用,可能就会对精度有点牺牲,所以我感觉我们用GPU来跑的话,用这个cmu模型效果应该会更好。
接着往下看,
logger.debug('initialization %s : %s' % (args.model, get_graph_path(args.model)))
w, h = model_wh(args.resize)
if w > 0 and h > 0:
e = TfPoseEstimator(get_graph_path(args.model), target_size=(w, h))
else:
e = TfPoseEstimator(get_graph_path(args.model), target_size=(432, 368))
TfPoseEstimator是个类,这里先实例化这个类,具体这个类干嘛的,我们先不管,继续往下看,
logger.debug('cam read+')
cam = cv2.VideoCapture(args.camera)
ret_val, image = cam.read()
logger.info('cam image=%dx%d' % (image.shape[1], image.shape[0]))
while True:
ret_val, image = cam.read()
logger.debug('image process+')
humans = e.inference(image, resize_to_default=(w > 0 and h > 0), upsample_size=args.resize_out_ratio)
logger.debug('postprocess+')
image = TfPoseEstimator.draw_humans(image, humans, imgcopy=False)
logger.debug('show+')
cv2.putText(image,
"FPS: %f" % (1.0 / (time.time() - fps_time)),
(10, 10), cv2.FONT_HERSHEY_SIMPLEX, 0.5,
(0, 255, 0), 2)
cv2.imshow('tf-pose-estimation result', image)
fps_time = time.time()
if cv2.waitKey(1) == 27:
break
logger.debug('finished+')
cv2.destroyAllWindows()
上面的代码就是先用opencv从摄像头中读取一帧一帧的图像数据,然后将图像数据传给TfPoseEstimator类的inference函数,得到一个返回值humans,humans和图像数据image再传给TfPoseEstimator类的draw_humans函数,得到的返回值通过opencv显示出来,就是我们看到的人体姿态检测图。可以猜一下,这个humans应该包含了人体的关键点信息,之所以是humans而不是human,应该是这个信息有可以同时包含多个人的,而draw_humans函数的功能则是根据这些信息和原始图像数据image,将这些关键点和其连接画到原始图像上。
5、draw_humans函数
为了验证上面的猜想是否正确,我们来看看draw_humans函数做了什么,先贴代码,
@staticmethod
def draw_humans(npimg, humans, imgcopy=False):
if imgcopy:
npimg = np.copy(npimg)
# 获取图片的高和宽
image_h, image_w = npimg.shape[:2]
centers = {}
# humans可能包含多个人的信息
for human in humans:
# draw point
for i in range(common.CocoPart.Background.value):
if i not in human.body_parts.keys():
continue
# 取出对应的关键点
body_part = human.body_parts[i]
# 计算关键点坐标,body_part中的值只是关键点相对图片的位置的比例,并不是真实的坐标值
# 加0.5应该是为了做四舍五入运算,因为图片中的坐标值一定得是整数的
center = (int(body_part.x * image_w + 0.5), int(body_part.y * image_h + 0.5))
centers[i] = center
# 用一个小圆点画出关键点
cv2.circle(npimg, center, 3, common.CocoColors[i], thickness=3, lineType=8, shift=0)
# draw line
for pair_order, pair in enumerate(common.CocoPairsRender):
# 关节两端的关键点同时检测到,才画直线
if pair[0] not in human.body_parts.keys() or pair[1] not in human.body_parts.keys():
continue
# npimg = cv2.line(npimg, centers[pair[0]], centers[pair[1]], common.CocoColors[pair_order], 3)
# 用直线将关节画出来
cv2.line(npimg, centers[pair[0]], centers[pair[1]], common.CocoColors[pair_order], 3)
return npimg
上面代码中的common.CocoPart类就包含了我们要检测的关键点,
class CocoPart(Enum):
Nose = 0
Neck = 1
RShoulder = 2
RElbow = 3
RWrist = 4
LShoulder = 5
LElbow = 6
LWrist = 7
RHip = 8
RKnee = 9
RAnkle = 10
LHip = 11
LKnee = 12
LAnkle = 13
REye = 14
LEye = 15
REar = 16
LEar = 17
Background = 18
而CocoPairsRender数组包含的是由对应关键点组成的关节的元祖,
CocoPairs = [
(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)
] # = 19
CocoPairsRender = CocoPairs[:-2]
为了方便理解,我用我魔性的绘画水准画出了下面的示意图,
为什么上图没有头发呢?因为程序员不需要头发的~
大家对比一下上面这张图就很好理解common.CocoPart类和CocoPairsRender数组了。为了方便后续查看,我给上面的CocoPairs加了注释,
CocoPairs = [
(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)
] # = 19
CocoPairsRender = CocoPairs[:-2]
其他的都比较好理解,直接看注释好了,后续的博客,我们先看原始论文的算法,再解析源码,这一讲就先到这里了。
如果您感觉本篇博客对您有帮助,请打开支付宝,领个红包支持一下,祝您扫到99元,谢谢~~
python 人体检测技术_tensorflow入门教程(四十三)人体姿态检测(一)相关推荐
- Android入门教程四十三之Spinner(列表选项框)的基本使用
本来本节是想给大家介绍一个Gallery(画廊)的一个控件的,后来想想还是算了,因为 在Android 4.1后就已经被弃用了,尽管我们可以通过兼容不来使用Gallery,不过想想 还是算了,因为Ga ...
- python很全的爬虫入门教程
python很全的爬虫入门教程 一.爬虫前的准备工作 首先,我们要知道什么是爬虫 1.什么是网络爬虫? 网络爬虫是一种按照一定的规则,自动的抓取万维网信息的程序或者脚本.另外一些不常使用的名字还有蚂蚁 ...
- 第三章 Python Kivy 学习 -- Kivy官方入门教程Pong Game
系列文章目录 第一章 Python Kivy 学习 – Kivy介绍及环境安装 第二章 Python Kivy 学习 – Kivy项目开发原理(待编辑) 第三章 Python Kivy 学习 – Ki ...
- keil obj 文件 结构_【Python】数据分析前的入门教程 Python For Everybody P2:数据结构...
这是密歇根大学课程Python For Everybody总结的P2部分.课程总结P1部分的地址如下: P1: 零基础程序设计(Python 入门) carolinezhq:[Python]数据分析前 ...
- LittleVGL (LVGL)干货入门教程四之制作和使用中文汉字字库
LittleVGL (LVGL)干货入门教程四之制作和使用中文汉字字库 前言: 阅读前,请确保你至少拥有以下条件: 已实现显示API(教程一已实现, 链接:LittleVGL (LVGL)入门教程一之 ...
- 【OpenCV入门教程之十三】OpenCV图像金字塔:高斯金字塔、拉普拉斯金字塔与图片尺寸缩放
本系列文章由@浅墨_毛星云 出品,转载请注明出处. 文章链接: http://blog.csdn.net/poem_qianmo/article/details/26157633 作者:毛星云(浅墨) ...
- 九宫怎么排列和使用_广告视频配音剪映零基础入门教程第二十三篇:剪辑之九宫格教程...
朋友圈最火九宫格视频你们知道是怎样制作的吗?我们常常在玩朋友圈的时候想用九宫格照片,但是你们有没有遇到这种情况,想玩九宫格却发现找不到那么多能用的照片,那这时候怎么办呢?玩腻了平常图片的发法,今天我们 ...
- tensorflow入门教程(四十四)人体姿态检测(二)
# #作者:韦访 #博客:https://blog.csdn.net/rookie_wei #微信:1007895847 #添加微信的备注一下是CSDN的 #欢迎大家一起学习 # ------韦访 2 ...
- python tensorflow教程_TensorFlow入门教程TensorFlow 基本使用T
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 TensorFlow入门教程 TensorFlow 基本使用 TensorFlow官方中文教程 TensorFlow 的特点: 使用图 (graph) 来 ...
最新文章
- .net简单算法实现无限级分类(一)
- 《Dreamweaver CS6完美网页制作——基础、实例与技巧从入门到精通》——1.3 常用网页设计软件...
- 微型计算机实验报告温度控制,单片机、可编程控制器实验教学大纲.doc
- java多线程详解(8)-volatile,Atomic比较
- javascript取随机数_一些常用Javascript 小技巧,值得你关注
- PyTorch 1.0 中文官方教程:Autograd:自动求导
- 《信息处理技术员考试考前冲刺预测卷及考点解析》下午案例复习重点
- 北京地铁票价查询系统 c++ Dijkstra算法
- JAVA 蹒跚自学之 第七日 数组选择 冒泡排序优化
- 利用TTL转USB串口在两台PC机间进行文件传输
- 《智慧书》格言大全(1-300)
- 模拟京东快递单号查询框
- JQuery常见命令查找网站
- Mac ZeroTire 的重启方式
- C语言怎样提取一个数的十位个位百位千位
- 老站长心语:网站由小到大的建站经历
- 数字孪生in卫星:数字化助力强国芯
- AtCoder Beginner Contest 168 C~D题解
- python实现网站测速软件_网站测速插件是什么-和网站测速插件相关的问题-阿里云开发者社区...
- 网络编程--TCP实例
热门文章
- IMAX中国创历史最佳十月纪录;强生、施华洛世奇将再亮相进博会;全球最大最高摩天轮迎来首批游客 | 美通社头条...
- Python爬虫之爬取绝对领域美女图片
- android播放器:MediaPlayer ExoPlayer ijkplayer
- 2011年国外最受欢迎的15个儿童网站
- 南方科技大学计算机学科评估,全国第四轮学科评估结果公布 我校7个学科进入B类...
- 原VIPKID研发副总裁朱会离职
- jenv add “ln No such file or directory“解决办法
- 新手如何运营推广微信公众号
- 系统架构-UML 包图
- 纯java手机通讯录