1.对全身图进行裁剪,生成局部行人数据作为训练集 √
裁剪方式共 4*3=12种:
(1)从上边/下边/左边/右边四个方向进行裁剪
(2)裁剪比例设为0.4、0.6、0.8
例如全身图片
从上边裁剪:
从下边裁剪:
从左边裁剪:
从右边裁剪:
2.计算每张图片的6个区域的坐标,保存在pkl文件中 √
#market-1501
import os
import pickle
import numpy as np
kpt_names = [
'nose',
'left_eye', 'right_eye',
'left_ear', 'right_ear',
'left_shoulder', 'right_shoulder',
'left_elbow', 'right_elbow',
'left_wrist', 'right_wrist',
'left_hip', 'right_hip',
'left_knee', 'right_knee',
'left_ankle', 'right_ankle'
]
kpt_name_to_ind = dict(zip(kpt_names, range(len(kpt_names))))
def fuse_y(kpts, l_name, r_name, fuse=np.mean):
l_kpt = kpts[kpt_name_to_ind[l_name]]
r_kpt = kpts[kpt_name_to_ind[r_name]]
if (l_kpt[2] == 1) and (r_kpt[2] == 1):
y = fuse([l_kpt[1], r_kpt[1]])
visible = True
elif (l_kpt[2] == 0) and (r_kpt[2] == 1):
y = r_kpt[1]
visible = True
elif (l_kpt[2] == 1) and (r_kpt[2] == 0):
y = l_kpt[1]
visible = True
else:
y = 0
visible = False
return y, visible
PARTS_DICT = {
'PAP_6P': ('HEAD', 'UPPER_TORSO', 'LOWER_TORSO', 'UPPER_LEG', 'LOWER_LEG', 'SHOES'),
'PAP_9P': ('HEAD', 'UPPER_TORSO', 'LOWER_TORSO', 'UPPER_LEG', 'LOWER_LEG', 'SHOES', 'UPPER_HALF', 'LOWER_HALF', 'WHOLE'),
}
def gen_pap_masks(im_h_w, h_w, kpts, mask_type='PAP_6P'):
"""Generate pap masks for one image.
Args:
im_h_w: size of image
h_w: size of pap masks
kpts: np array or a list with shape [num_kpts, 3], kpts[i] is (x, y, visibility)
Returns:
masks: numpy array (float32) with shape [num_masks, h, w]
visible: numpy array (float32) with shape [num_masks]. If some keypoints are invisible, related parts may be unavailable.
"""
parts = PARTS_DICT[mask_type]
kpts = np.array(kpts)
assert len(kpts.shape) == 2
assert kpts.shape[1] == 3
P = kpts.shape[0]
H, W = h_w
masks = []
visible = []
def _to_ind(y):
return min(H, max(0, int(1. * H * y / im_h_w[0] + 0.5)))
def _to_ind_x(x):
return min(W, max(0, int(1. * W * x / im_h_w[1] + 0.5)))
def _gen_mask(y1, y2, v, part_name='', debug=False):
if debug and v and y1 >= y2:
print('[Warning][{:15}] y1 {:2d}, y2 {:2d}, v {}'.format(part_name, y1, y2, v))
v = v and (y1 < y2)
m = np.zeros([H, W], dtype=np.float32)
# Return 0 mask if invisible
if v:
m[y1:y2] = 1
masks.append(m)
visible.append(v)
return m, v
# Exclude upper background
def _gen_HEAD_mask():
return [max(0, shoulder_y - int(np.ceil(H * 0.25))), shoulder_y,int(shoulder_v)]
#return _gen_mask(max(0, shoulder_y - int(np.ceil(H * 0.25))), shoulder_y, shoulder_v, part_name='HEAD')
def _gen_UPPER_TORSO_mask():
return [shoulder_y, shoulder_hip_mid_y, int(shoulder_hip_mid_v)]
#return _gen_mask(shoulder_y, shoulder_hip_mid_y, shoulder_hip_mid_v, part_name='UPPER_TORSO')
def _gen_LOWER_TORSO_mask():
return [shoulder_hip_mid_y, hip_y, int(shoulder_hip_mid_v)]
#return _gen_mask(shoulder_hip_mid_y, hip_y, shoulder_hip_mid_v, part_name='LOWER_TORSO')
def _gen_UPPER_LEG_mask():
return [hip_y, knee_y, int(hip_v and knee_v)]
#return _gen_mask(hip_y, knee_y, hip_v and knee_v, part_name='UPPER_LEG')
# Here LOWER_LEG is without shoes
def _gen_LOWER_LEG_mask():
if knee_v and ankle_v:
return [knee_y, ankle_y, 1]
#return _gen_mask(knee_y, ankle_y, True, part_name='LOWER_LEG')
elif knee_v:
return [knee_y, min(H, knee_y + int(np.ceil(H * 0.25))), 1]
#return _gen_mask(knee_y, min(H, knee_y + int(np.ceil(H * 0.25))), True, part_name='LOWER_LEG')
else:
return [0, H, 0]
#return _gen_mask(0, H, False, part_name='LOWER_LEG')
def _gen_circle_mask(h_w, pt, radius):
"""A circle region.
pt: head center point
"""
h, w = h_w
x, y = pt
xv, yv = np.arange(w)[np.newaxis, :], np.arange(h)[:, np.newaxis]
return ((xv - x) ** 2 + (yv - y) ** 2 <= radius ** 2).astype(np.float32)
def _gen_SHOES_mask():
radius = int(0.5 * H / 6)
left_ankle_kpt = kpts[kpt_name_to_ind['left_ankle']]
left_shoes_mask = _gen_circle_mask((H, W), (_to_ind_x(left_ankle_kpt[0]), _to_ind(left_ankle_kpt[1])), radius) if left_ankle_kpt[2] == 1 else np.zeros([H, W], dtype=np.float32)
right_ankle_kpt = kpts[kpt_name_to_ind['right_ankle']]
right_shoes_mask = _gen_circle_mask((H, W), (_to_ind_x(right_ankle_kpt[0]), _to_ind(right_ankle_kpt[1])), radius) if right_ankle_kpt[2] == 1 else np.zeros([H, W], dtype=np.float32)
shoes_mask = np.logical_or(left_shoes_mask, right_shoes_mask).astype(np.float32)
if left_ankle_kpt[2] == 1 and right_ankle_kpt[2] == 1:
top=(_to_ind(left_ankle_kpt[1])+_to_ind(right_ankle_kpt[1]))/2-radius
down=(_to_ind(left_ankle_kpt[1])+_to_ind(right_ankle_kpt[1]))/2+radius
elif left_ankle_kpt[2] == 1:
top = _to_ind(left_ankle_kpt[1]) - radius
down = _to_ind(left_ankle_kpt[1]) + radius
elif right_ankle_kpt[2] == 1:
top = _to_ind(right_ankle_kpt[1]) - radius
down = _to_ind(right_ankle_kpt[1]) + radius
else:
top=0
down=H
return [top,down,int(ankle_v)]
# masks.append(shoes_mask)
# visible.append(ankle_v)
# return shoes_mask, ankle_v
def _gen_UPPER_HALF_mask():
return _gen_mask(0, hip_y, hip_v, part_name='UPPER_HALF')
# If knee and ankle are both invisible, view lower half as invisible
def _gen_LOWER_HALF_mask():
return _gen_mask(hip_y, H, hip_v and (knee_v or ankle_v), part_name='LOWER_HALF')
def _gen_WHOLE_mask():
return _gen_mask(0, H, True, part_name='WHOLE')
shoulder_y, shoulder_v = fuse_y(kpts, 'left_shoulder', 'right_shoulder')
hip_y, hip_v = fuse_y(kpts, 'left_hip', 'right_hip')
knee_y, knee_v = fuse_y(kpts, 'left_knee', 'right_knee')
ankle_y, ankle_v = fuse_y(kpts, 'left_ankle', 'right_ankle')
shoulder_hip_mid_y, shoulder_hip_mid_v = (shoulder_y + hip_y) * 0.5, shoulder_v and hip_v
shoulder_y, hip_y, knee_y, shoulder_hip_mid_y, ankle_y = _to_ind(shoulder_y), _to_ind(hip_y), _to_ind(knee_y), _to_ind(shoulder_hip_mid_y), _to_ind(ankle_y)
res=[]
for p in parts:
res.append(eval('_gen_{}_mask()'.format(p)))
return res
# masks = np.array(masks, dtype=np.float32)
# visible = np.array(visible, dtype=np.float32)
# return masks, visible
if __name__=='__main__':
market_train_firectory='C:\\Users\\刘咏\Documents\\行人重识别\\普通数据集\\market-1501-v15.09.15\\Market-1501-v15.09.15\\bounding_box_train'
files = os.listdir(market_train_firectory)
kpt_path='C:\\Users\\刘咏\\PycharmProjects\\part_erase_network\\im_path_to_kpt.pkl'
with open(kpt_path, 'rb') as f:
im_path_to_kpt = pickle.load(f)
img_path_to_part={}
for file in files:
if '.jpg' not in file:continue
file='bounding_box_train/'+file
kpt = im_path_to_kpt[file]['kpt']
kpt[:, 2] = (kpt[:, 2] > 0.1).astype(np.float)
pap_mask= gen_pap_masks(im_path_to_kpt[file]['im_h_w'],im_path_to_kpt[file]['im_h_w'],kpt)
img_path_to_part[file]=pap_mask
save_path=kpt_path='C:\\Users\\刘咏\\PycharmProjects\\part_erase_network\\img_path_to_part_index.pkl'
with open(save_path, 'wb') as handle:
pickle.dump(img_path_to_part,handle)
复制代码
3. 统计距离信息
mean std 结论
AGlobal_BGlobal: 15.7 1.8 不同人的global特征多数时候差距小
ALolcal_ALocal: 21/4 24/140 同个人的local特征差距波动大
ALocal_BLocal: 25/13 9/62 不同人的local特征差距较大
AGlobal_ALocal: 1022/8066 10338/109720370 同个人的global和local差距巨大
复制代码