1.root_path = './'
raw_data_file = osp.join(root_path, 'raw_data', 'raw_skes_data.pkl')
save_path = osp.join(root_path, 'denoised_data')-》载入上一个文件处理后的.pkl文件路径
2.if not osp.exists(save_path):
os.mkdir(save_path)-》如果保存路径不存在则创建此路径
3.rgb_ske_path = osp.join(save_path, 'rgb+ske')
if not osp.exists(rgb_ske_path):
os.mkdir(rgb_ske_path)-》创建save_path路径下的rgb+ske文件夹
4.actors_info_dir = osp.join(save_path, 'actors_info')
if not osp.exists(actors_info_dir):
os.mkdir(actors_info_dir)-》创建save_path路径下的actors_info文件夹
5.missing_count = 0
noise_len_thres = 11
noise_spr_thres1 = 0.8
noise_spr_thres2 = 0.69754
noise_mot_thres_lo = 0.089925
noise_mot_thres_hi = 2-》创建各种参数
6.noise_len_logger = logging.getLogger('noise_length')-》创建日志
noise_len_logger.setLevel(logging.INFO)-》设置日志等级
noise_len_logger.addHandler(logging.FileHandler(osp.join(save_path, 'noise_length.log')))-》存储日志
noise_len_logger.info('{:^20}\t{:^17}\t{:^8}\t{}'.format('Skeleton', 'bodyID', 'Motion', 'Length'))-》日志信息格式
首先介绍get_raw_denoised_data方法
1.此函数功能:从原始骨架序列中获取去噪数据(关节位置和颜色位置)。
解释:对于骨骼序列的每一帧,都表示一个演员的25个关节的三维位置通过一个二维数组(形状:25 x 3)被重新塑造成一个75-维矢量通过连接每个3-维(x, y, z)坐标沿行维按关节顺序排列。每一帧包含两个演员的关节位置构成一个150-维向量。如果只有一个演员,然后最后75个值被0填充。否则,选择主参与者和第二个演员基于动作量。将每个150-维向量作为行向量放入一个二维numpy数组,其中行数等于有效帧数。所有这些2D数组被放到一个列表中,最后这个列表被序列化到一个cPickle文件中。对于包含两个或更多参与者的骨架序列(大多对应于最后11个类),文件名和参与者的信息被记录到日志文件中。为了更好地理解,还可以生成可视化的RGB+骨架视频。
2.with open(raw_data_file, 'rb') as fr: # load raw skeletons data
raw_skes_data = pickle.load(fr)-》打开.pkl文件
3.num_skes = len(raw_skes_data)
print('Found %d available skeleton sequences.' % num_skes)-》打印文件有多少数据总量
3.raw_denoised_joints = []
raw_denoised_colors = []
frames_cnt = []-》创建3个空数组
4. for (idx, bodies_data) in enumerate(raw_skes_data):-》遍历.pkl文件取出id和骨骼名
ske_name = bodies_data['name']-》取出bodies_data中ID为name这一列的值
print('Processing %s' % ske_name)-》打印
num_bodies = len(bodies_data['data'])-》取出“”data“”列的数据长度
5.if num_bodies == 1: # only 1 actor-》如果帧中只有一个人物
num_frames = bodies_data['num_frames']-》获取此人的动作帧数
body_data = list(bodies_data['data'].values())[0]-》取出骨骼数据的第一行
joints, colors = get_one_actor_points(body_data, num_frames)-》获取关节和像素值
else: -》 超过一个演员,选择两个主要演员
joints, colors = get_two_actors_points(bodies_data)-》获取两个演员的关节
# Remove missing frames
joints, colors = remove_missing_frames(ske_name, joints, colors)-》移除掉有丢失的帧的关节像素。
num_frames = joints.shape[0] # 更新关节总数
6. raw_denoised_joints.append(joints)
raw_denoised_colors.append(colors)
frames_cnt.append(num_frames)-》把joints,colors,num_frames传入数组变量
7.if (idx + 1) % 1000 == 0:
print('Processed: %.2f%% (%d / %d), ' % \
(100.0 * (idx + 1) / num_skes, idx + 1, num_skes) + \
'Missing count: %d' % missing_count)-》每处理1000次打印一次处理信息
8.
raw_skes_joints_pkl = osp.join(save_path, 'raw_denoised_joints.pkl')
with open(raw_skes_joints_pkl, 'wb') as f:
pickle.dump(raw_denoised_joints, f, pickle.HIGHEST_PROTOCOL)
raw_skes_colors_pkl = osp.join(save_path, 'raw_denoised_colors.pkl')
with open(raw_skes_colors_pkl, 'wb') as f:
pickle.dump(raw_denoised_colors, f, pickle.HIGHEST_PROTOCOL)-》打开raw_denoised_joints.pkl和raw_denoised_colors.pkl文件
9.
frames_cnt = np.array(frames_cnt, dtype=np.int)
np.savetxt(osp.join(save_path, 'frames_cnt.txt'), frames_cnt, fmt='%d')
print('Saved raw denoised positions of {} frames into {}'.format(np.sum(frames_cnt),
raw_skes_joints_pkl))
print('Found %d files that have missing data' % missing_count)-》保存总帧数到指定路径的txt文件里面去。
解读get_two_actors_points方法:
作用:获得第一个和第二个演员的关节位置和颜色位置。
数据构成:bodies_data (dict): 3个键值对:'name', 'data', 'num_frames'。
bodies_data['data'] 也是一个字典, 当这个键是身体ID, 值是对应的身体数据(关节像素),它也是一个有4个键的字典:
关节:原始的三维关节位置。形状:(num_frames x 25,3)
颜色:原始的2D颜色位置。形状:(num_frames, 25,2)
间隔:记录帧索引的列表。
运动:运动数量
返回的是关节,颜色坐标。
1.ske_name = bodies_data['name']-》提取骨骼名
2.label = int(ske_name[-2:])-》取出所有name作为标签。
3.num_frames = bodies_data['num_frames']-》去帧总数
4.bodies_info = get_bodies_info(bodies_data['data'])-》取body数据
5. bodies_data, noise_info = denoising_bodies_data(bodies_data) -》把body数据放入去噪方法中处理
bodies_info += noise_info-》作body信息和噪声信息的和
6. bodies_data = list(bodies_data)-》放入列表
7.if len(bodies_data) == 1: -》判断body数据是不是一个人的
if label >= 50: -》双主体动作去噪失败
fail_logger_2.info(ske_name)-》记录日志
bodyID, body_data = bodies_data[0]-》取body数据第一个的ID和数据
joints, colors = get_one_actor_points(body_data, num_frames)-》将body数据和总帧数传入get_one_actor_points取出关节和像素
bodies_info += 'Main actor: %s' % bodyID-》将ID加入到bodies_info 中
else:
if label < 50: -》单主体动作去噪失败
fail_logger_1.info(ske_name)-》记录日志
8.joints = np.zeros((num_frames, 150), dtype=np.float32)-》建立一个行数为总帧数,150列的填充0的矩阵
9.colors = np.ones((num_frames, 2, 25, 2), dtype=np.float32) * np.nan-》建立一个带总帧数的以1为填充的4维矩阵。
10.bodyID, actor1 = bodies_data[0]-》取body数据第一个的ID和数据
11.start1, end1 = actor1['interval'][0], actor1['interval'][-1]-》记录bodies_data[0]行为数据的第一行和最后一行
12.joints[start1:end1 + 1, :75] = actor1['joints'].reshape(-1, 75)--》取出行为数据中的关节数据
13.colors[start1:end1 + 1, 0] = actor1['colors']--》取出行为数据中的像素数据
14.actor1_info = '{:^17}\t{}\t{:^8}\n'.format('Actor1', 'Interval', 'Motion') + \
'{}\t{:^8}\t{:f}\n'.format(bodyID, str([start1, end1]), actor1['motion'])-》匹配正则表达式的字符串
15. del bodies_data[0]-》删除bodies_data[0]对象
16.actor2_info = '{:^17}\t{}\t{:^8}\n'.format('Actor2', 'Interval', 'Motion')-》-》匹配正则表达式的字符串
17.start2, end2 = [0, 0] -》actor2的初始间隔(虚拟)
18.while len(bodies_data) > 0:-》如果数据不为空
bodyID, actor = bodies_data[0]-》取body数据第一个的ID和数据
start, end = actor['interval'][0], actor['interval'][-1]-》记录actor中间隔数据的第一行和最后一行
19.if min(end1, end) - max(start1, start) <= 0: -》与actor1没有重叠
joints[start:end + 1, :75] = actor[&