加载准备好的数据(训练前的数据)
- .h5 的数据是通过代码的预处理操作得到的
- 原本的数据只有一个 COCO 数据集,通过预处理步骤,将数据整合成一个 .h5 的训练文件
- 这里使用的代码是 基于 keras 的 openpose,源码网址在:
https://github.com/kevinlin311tw/keras-openpose-reproduce
import numpy as np
import cv2
import matplotlib.pyplot as plt
from matplotlib import cm as c
import os
import math
'''我自己的工作路径,在本文中与工作路径的问题,大家需要自己调一下'''
os.chdir("../mycodes/keras-openpose-reproduce/")
from py_rmpe_server.py_rmpe_data_iterator import *
数据路径
h5file = "../../datasets/val_dataset_2017.h5"
'''程序中定义好的加载数据的类,aug 要选 False 否则会进行数据增强,
数据会被裁剪和旋转,不利于我们可视化的过程'''
raw_data_iterator = RawDataIterator(h5file,augment=False)
通过 next 从 generator 中获取一张图片的数据 + 标签
gene = raw_data_iterator.gen()
img,mask,labels,joints = next(gene)
'''下图中的黑边是因为对不同尺寸的图片进行了 pad 操作,为了输入尺寸一致'''
b,g,r = img[0],img[1],img[2]
img_ = cv2.merge([r,g,b])
plt.imshow(img_)
label 的 [0-38) 通道是 PAF 的 label,[38-57) 是 heatmap 的 label
labels.shape
(57, 46, 46)
取前 38 通道并把通道调整为(46,46,38)
pafs = labels[:38,:,:].transpose([1,2,0])
pafs.shape
(46, 46, 38)
img_.shape
(368, 368, 3)
- 每个 PAF 的标签占据两个通道,这两个通道分别代表:
- 某个 limb PAF 的 x 方向坐标矩阵
- 某个 limb PAF 的 y 方向的坐标矩阵
pafs_shape = pafs.shape
x,y = np.meshgrid(np.arange(pafs_shape[0]),np.arange(pafs_shape[1]))
'''可视化一下 x 方向 limb 的分量'''
u = pafs[:,:,0]
v = pafs[:,:,1]m = np.zeros((46,46),dtype="bool")
m[u**2 &#43; v**2 < 0.5**2] &#61; Truefrom numpy import ma
u &#61; ma.masked_array(u,mask&#61;m)
v &#61; ma.masked_array(v,mask&#61;m)
&#39;&#39;&#39; stride &#xff0c;在 X,Y 构成的坐标图上&#xff0c;每隔 stride 个像素点画一个向量&#39;&#39;&#39;
s &#61; 2 plt.quiver(x[::s],y[::s],u[::s],v[::s],color&#61;"r")&#39;&#39;&#39;注意&#xff0c; plt.quiver 和 plt.imshow 的时候&#xff0c;他们的 y 轴坐标的起始是不同的&#39;&#39;&#39;
plt.imshow(pafs[:,:,0])
在 PAF label 上画出对应的矢量场
plt.quiver(x[::s],y[::s],u[::s],v[::s],color&#61;"r")
plt.imshow(pafs[:,:,0])
pafs[:,:,0].max()
0.08548474821581316
将矢量图叠加到原图上
- 由于原图尺寸被 pad 成了 (368,368) 因此&#xff0c;我们先将 label resize 成和 img 对应尺寸
- 由于 PAF 图的数据值的分布范围在 0-1 &#xff0c;因此我们需要对他进行操作&#xff0c;normalize 成 (0-255) 之间的 uint类型&#xff0c;才能进行 opencv 的操作
- 最后我们采用 cv2.addweighted 对图进行叠加
X,Y &#61; np.meshgrid(np.arange(368),np.arange(368))
U &#61; cv2.resize(pafs[:,:,0],(368,368),cv2.INTER_CUBIC)
V &#61; cv2.resize(pafs[:,:,1],(368,368),cv2.INTER_CUBIC)
M &#61; np.zeros((368,368),dtype&#61;"bool")
M[U**2 &#43; V**2 < 0.5 * 0.5] &#61; True
from numpy import ma
U &#61; ma.masked_array(U, mask&#61;M)
V &#61; ma.masked_array(V, mask&#61;M)
plt.figure()
plt.imshow(img_, alpha &#61; .5)
s &#61; 5
Q &#61; plt.quiver(X[::s,::s], Y[::s,::s], U[::s,::s], V[::s,::s], scale&#61;50, headaxislength&#61;4, alpha&#61;.5, width&#61;0.001, color&#61;&#39;r&#39;)
fig &#61; plt.gcf()
fig.set_size_inches(20, 20)
将所有的身体部分的场放到一个图中
首先展示一个 image 中 38 个通道的所有 PAF label
figure &#61; plt.figure(figsize&#61;(120,200))
for i in range(pafs.shape[2] // 2):axes &#61; figure.add_subplot(8, 5, i&#43;1)plt.imshow(pafs[:,:,2*i])
plt.show()
按照 x 和 y 分别叠加其分别的 19 个通道的矢量图
&#39;&#39;&#39;矢量图中的第偶数个&#xff0c;但是他们对应通道的索引是偶数&#39;&#39;&#39;
odd &#61; [i for i in range(pafs.shape[2]) if i % 2 &#61;&#61; 0]
&#39;&#39;&#39;矢量图中的第偶数个&#xff0c;但是他们对应通道的索引都是奇数&#39;&#39;&#39;
even &#61; [i for i in range(pafs.shape[2]) if i % 2 !&#61; 0]
final_x &#61; np.amax(pafs[:,:,odd],axis&#61;2)
final_y &#61; np.amax(pafs[:,:,even],axis&#61;2)
pafs.shape
(46, 46, 38)
plt.imshow(final_x)
plt.imshow(final_y)
展示整个 PAF 矢量图叠加在原图上
U &#61; cv2.resize(final_x,(368,368),cv2.INTER_CUBIC)
V &#61; cv2.resize(final_y,(368,368),cv2.INTER_CUBIC)
M &#61; np.zeros((368,368),dtype&#61;"bool")
M[U**2 &#43; V**2 < 0.5 * 0.5] &#61; True
U &#61; ma.masked_array(U, mask&#61;M)
V &#61; ma.masked_array(V, mask&#61;M)
plt.figure()
plt.imshow(img_, alpha &#61; .5)
s &#61; 2
Q &#61; plt.quiver(X[::s,::s], Y[::s,::s], U[::s,::s], V[::s,::s], scale&#61;50, headaxislength&#61;4, alpha&#61;.5, width&#61;0.001, color&#61;&#39;r&#39;)
fig &#61; plt.gcf()
fig.set_size_inches(20, 20)
可视化小拓展&#xff1a;
- 在这篇文章中&#xff0c;作者将 PAF 的 imshow 的图和原图进行叠加&#xff0c;用的是 cv2.addweighted 大家有兴趣可以查看&#xff0c;最终的结果是这样的
https://blog.csdn.net/hjxu2016/article/details/111035439