欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

《Learning to Estimate 3D Hand Pose from Single RGB Images》代码运行阅读笔记

程序员文章站 2022-04-16 16:24:33
...

读懂这个文章的代码,并能在自己的照片上测试

文章链接

代码链接

环境搭建

环境是很久以前搭的,已经忘了。不过按照github中的readme一步一步来基本没问题。

数据集

根据文章中所讲目前可用的带关键点位置的RGB数据集有:Steror和Dexter。NYU数据集主要用于深度图不作考虑。不过这两个数据集太小,而且人工标注不够精确,所以用模型生成的数据做一个补充(工具:MixamoBlender背景)。一共有320*320大小的41258张训练图像和2728张测试图像。

《Learning to Estimate 3D Hand Pose from Single RGB Images》代码运行阅读笔记

值得注意的是文章中说有深度图的数据和分割标签。

《Learning to Estimate 3D Hand Pose from Single RGB Images》代码运行阅读笔记

网络训练

训练分三个阶段,HandSegNet对应程序中的training_handsegnet.py,PoseNet对应程序中的training_posenet.py,PosePrior、ViewPoint对应程序中的training_lifting.py

《Learning to Estimate 3D Hand Pose from Single RGB Images》代码运行阅读笔记

  • training_handsegnet.py

1:训练数据读取

创建一个dataset对象,其中存放了读取数据需要的信息,比较重要的有:batch大小、噪音设置、图片大小320*320、样本数量41258、数据集路径rhd、shuffle是否打乱顺序等信息。

《Learning to Estimate 3D Hand Pose from Single RGB Images》代码运行阅读笔记

用dataset.get()读取需要的数据。

《Learning to Estimate 3D Hand Pose from Single RGB Images》代码运行阅读笔记

2:搭建网络

搭建网络的各种层的具体操作封装在NetworkOps类里面。

网络输入:图像8*256*256*3和权重(true or false)是否更改

网络输出:8*256*256*2的特征,与标签mask一致

 

数据读取操作和根据图片都是用tensorflow的计算图进行的,分别封装在dataset类和ColorHandPose3DNetwork类里面

# build network
evaluation = tf.placeholder_with_default(True, shape=())
net = ColorHandPose3DNetwork()
hand_mask_pred = net.inference_detection(data['image'], train=True)

3:开启session

# Start TF
gpu_options = tf.GPUOptions(per_process_gpu_memory_fraction=0.8)
sess = tf.Session(config=tf.ConfigProto(gpu_options=gpu_options))
tf.train.start_queue_runners(sess=sess)

4:逐点计算loss,计算梯度,设置学习率

# Loss
loss = 0.0
s = data['hand_mask'].get_shape().as_list()
for i, pred_item in enumerate(hand_mask_pred):
    gt = tf.reshape(data['hand_mask'], [s[0]*s[1]*s[2], -1])
    pred = tf.reshape(hand_mask_pred, [s[0]*s[1]*s[2], -1])
    loss += tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=pred, labels=gt))

# Solver
global_step = tf.Variable(0, trainable=False, name="global_step")
lr_scheduler = LearningRateScheduler(values=train_para['lr'], steps=train_para['lr_iter'])
lr = lr_scheduler.get_lr(global_step)
opt = tf.train.AdamOptimizer(lr)
train_op = opt.minimize(loss)

5:初始化权重,加载参数

《Learning to Estimate 3D Hand Pose from Single RGB Images》代码运行阅读笔记

# init weights
sess.run(tf.global_variables_initializer())
saver = tf.train.Saver(max_to_keep=1, keep_checkpoint_every_n_hours=4.0)

rename_dict = {'CPM/PersonNet': 'HandSegNet',
               '_CPM': ''}
load_weights_from_snapshot(sess, './weights/cpm-model-mpii', ['PoseNet', 'Mconv', 'conv6'], rename_dict)
  • training_posenet.py和training_lifting.py也是类似的操作顺序

网络测试

修改run.py,把输入数据换成自己的摄像头获取的数据,把显示改成连续显示。连接自己的摄像头实验效果如下:

《Learning to Estimate 3D Hand Pose from Single RGB Images》代码运行阅读笔记

1:相机使用

把相机插上,然后运行如下代码,应该就可以获取了。

import cv2

cap = cv2.VideoCapture(0)

_,image_raw =  cap.read()

2:图像整形

将获取的图像缩放到240**320大小,并归一化到0~1范围。

image_raw = scipy.misc.imresize(image_raw, (240, 320))
image_v = np.expand_dims((image_raw.astype('float') / 255.0) - 0.5, 0)

3:网络计算

 整个流程: HandSegNet + PoseNet + PosePrior.

    Inputs:
        image: [B, H, W, 3] tf.float32 tensor, Image with mean subtracted
        hand_side: [B, 2] tf.float32 tensor, one hot encoding 需要限制为左手
        evaluation: [] tf.bool tensor, True while evaluation false during training (controls dropout)

    Outputs:
        hand_scoremap: [B, H, W, 2] 像素点是否属于手部的得分
        image_crop: [B, 256, 256, 3] 切出来的手部图像,并进行缩放
        scale_crop: [B, 1] 切分出来的手部相对于原图的大小
        center: [B, 1] 切出来的手部中心位置
        keypoints_scoremap: [B, 256, 256, 21] 每个手部关节点的概率图
        keypoint_coord3d: [B, 21, 3] 3D关节点位置

注意,最后2D和3D之间,不仅仅是相机矩阵转换和预测3D点位置而已,3D的似乎更符合运动学规律。

 

 

相关标签: 手势识别