openpose二维骨架搭建介绍及代码撰写详解(总结4)
可以从本人以前的文章中可以看出作者以前从事的是嵌入式控制方面相关的工作,是一个机器视觉小白,之所以开始入门机器视觉的学习主要是一个idea,想把机器视觉与控制相融合未来做一点小东西。废话不多说开始正题。(如有侵权立即删稿)
摘要
本文是介绍openpose网络二维骨架搭建,个人对其的知识总结,以及结合论文进行讲解,网络设计的知识点,代码撰写部分本人是借鉴的大佬的源码(下文会给出网址),基于pytorch编写代码。作为一个刚入门的小白怎么去学习别人的代码,一步一步的去理解每一行代码,怎么将网络设计变成代码,模仿大佬的代码去撰写。作为小白如有不足之处请批评指正哈。
openpose
在网络设计之前需要明白什么是openpose。
以下是我借鉴的文章以及视频的参考链接:
【强推!B站最通俗易懂的OpenPose实战教程:基于OpenPose实现人体姿态估计+目标追踪!看完就能写进简历(深度学习/计算机视觉)】
论文openpose下载链接
github代码参考链接:https://github.com/Hzzone/pytorch-openpose
在上文的哪个视频中很多知识点以及算法的介绍都已经很详细了。本文就不做过多介绍算法了,只浅层的提一下。
这张图片来自上文的视频。可以从图片中看出有18个点构成了人体的骨架,骨架节点的多少取决于你想训练啥,具体怎么训练本人也没有过多的深挖。
十八张特征图,概率用高斯分布的图像表示 。
网络结构设计
这张图本人没有在论文中找着,不知道为啥没有。具体讲解一下这张图,结合代码讲解一下。可以看出图像输入分成了两个部分,一个用来算关节点的位置,另一个分支用来算x,y轴向量大小。除第一个Stage1是3x3卷积以外,其他的Stage都是7x7的卷积网络设计。
1.首先定义Stage1因为其是3x3卷积,分别定义两个分支。
# Stage 1 分别定义了两个不同的分支(L1和L2),这通常对应于不同的人体关键点的输出
block1_1 = OrderedDict([
('conv5_1_CPM_L1', [128, 128, 3, 1, 1]),
('conv5_2_CPM_L1', [128, 128, 3, 1, 1]),
('conv5_3_CPM_L1', [128, 128, 3, 1, 1]),
('conv5_4_CPM_L1', [128, 512, 1, 1, 0]),
('conv5_5_CPM_L1', [512, 38, 1, 1, 0])
])
block1_2 = OrderedDict([
('conv5_1_CPM_L2', [128, 128, 3, 1, 1]),
('conv5_2_CPM_L2', [128, 128, 3, 1, 1]),
('conv5_3_CPM_L2', [128, 128, 3, 1, 1]),
('conv5_4_CPM_L2', [128, 512, 1, 1, 0]),
('conv5_5_CPM_L2', [512, 19, 1, 1, 0])
])
2.通过for循环实现stage2-6的遍历。
# 循环创建第二到第六阶段的卷积层,采用类似的结构,每个阶段有两个分支(L1和L2)
for i in range(2, 7):
blocks['block%d_1' % i] = OrderedDict([
('Mconv1_stage%d_L1' % i, [185, 128, 7, 1, 3]),
('Mconv2_stage%d_L1' % i, [128, 128, 7, 1, 3]),
('Mconv3_stage%d_L1' % i, [128, 128, 7, 1, 3]),
('Mconv4_stage%d_L1' % i, [128, 128, 7, 1, 3]),
('Mconv5_stage%d_L1' % i, [128, 128, 7, 1, 3]),
('Mconv6_stage%d_L1' % i, [128, 128, 1, 1, 0]),
('Mconv7_stage%d_L1' % i, [128, 38, 1, 1, 0])
])
blocks['block%d_2' % i] = OrderedDict([
('Mconv1_stage%d_L2' % i, [185, 128, 7, 1, 3]),
('Mconv2_stage%d_L2' % i, [128, 128, 7, 1, 3]),
('Mconv3_stage%d_L2' % i, [128, 128, 7, 1, 3]),
('Mconv4_stage%d_L2' % i, [128, 128, 7, 1, 3]),
('Mconv5_stage%d_L2' % i, [128, 128, 7, 1, 3]),
('Mconv6_stage%d_L2' % i, [128, 128, 1, 1, 0]),
('Mconv7_stage%d_L2' % i, [128, 19, 1, 1, 0])
])
3.两个分支的融合通过cat实现,因此类推实现6个stage。
def forward(self, x):
# 将来自两个分支的输出out1_1和out1_2与原始的out1拼接在一起,形成新的输出out2
out1 = self.model0(x)
#第一个都是3x3后续都是7x7
out1_1 = self.model1_1(out1)
out1_2 = self.model1_2(out1)
out2 = torch.cat([out1_1, out1_2, out1], 1)
out2_1 = self.model2_1(out2)
out2_2 = self.model2_2(out2)
out3 = torch.cat([out2_1, out2_2, out1], 1)
out3_1 = self.model3_1(out3)
out3_2 = self.model3_2(out3)
out4 = torch.cat([out3_1, out3_2, out1], 1)
out4_1 = self.model4_1(out4)
out4_2 = self.model4_2(out4)
out5 = torch.cat([out4_1, out4_2, out1], 1)
out5_1 = self.model5_1(out5)
out5_2 = self.model5_2(out5)
out6 = torch.cat([out5_1, out5_2, out1], 1)
out6_1 = self.model6_1(out6)
out6_2 = self.model6_2(out6)
return out6_1, out6_2
如图所示可以很明显的看出out2的组成,以上就是实现网络算法的主要部分。
接下来讲解代码的调试
代码借鉴来源于:上文链接
pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple
如果你是用github链接下载,注意下载权重。
body显示效果如图所示
test.py
test代码设计的初衷是不用ffprobe生成视频,再下一个包,太麻烦了,直接用opencv打开的。
完成以上步骤后点击运行即可。
测试效果如图所示,gif动图放不了。
以上就是本人的心得与总结,如有不足之处请多多包涵。
百度网盘链接代码权值及测试视频
链接: https://pan.baidu.com/s/17DkHQK8jRFMoobScJiZh-A?pwd=1esu
提取码: 1esu