partial re-ID

本文介绍了一种处理行人图像数据的方法,包括通过不同裁剪方式生成局部行人数据作为训练集,以及计算图片关键区域坐标。此外,还探讨了不同人与同一个人之间的全局与局部特征差距,为行人重识别提供了深入的分析。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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差距巨大
复制代码
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值