Video_based_ReID_01

Video-based pedestrian re-identification-01

1. Know the mars data set

Research on video pedestrian re-recognition basically cannot bypass the mars data set. As a more recognized data set for video pedestrian re-recognition, the excellent papers of each top issue are improving the rank of the mars data set.

So first, let us get to know this data set:
data set address
info file

We download the content in the above link, and then unzip it and save it in the following way:
Insert picture description hereThen, explain the content in these folders:

1.1 bbox_train

In the bbox_train folder, there are 625 subfolders (representing 625 pedestrian ids), which contain a total of 8,298 tracklets, and a total of 509,914 pictures.
Insert picture description hereNote: The names of the folders here are not consecutive!

Open any folder to see these contents: (explained after the file name)
Insert picture description here

1.2 bbox_test

There are a total of 636 subfolders in the bbox_test folder (representing 636 pedestrian ids), a total of 12,180 tracklets (tracklets), a total of 681,089 pictures. In the experiment, this folder was divided into gallery + query set. This will be explained in the info folder.
Insert picture description hereNote that they are not continuous! ! ! !

The subfolder named 00-1 represents useless picture collections, and their corresponding pedestrian id is set to **-1**, and pictures with pid = -1 are generally ignored in the algorithm.
Insert picture description here

In the name 0000 subfolder, their corresponding pedestrian id is set to 0, which indicates interference factors and negatively affects the accuracy of retrieval.
Insert picture description here

1.3 info

The info folder contains 5 sub-files, which contain the information of the entire data set, in order to facilitate the use of the data set.Insert picture description here

1.3.1 train_name.txt

In this txt file, the names of all pictures in the bbox_train folder are stored in order, with a total of 509,914 lines (corresponding to 509914 pictures).
Insert picture description herePicture name explanation:
0001 C1 T0001 F0001.jpg as an example.
0001 represents the id of the pedestrian, which is the corresponding 0001 subfolder name in the bbox_train folder;
C1 represents the id of the camera, indicating that this picture was taken under the first camera (a total of 6 cameras);
T0001 said Regarding the first
short video (tracklet) in this pedestrian video segment; F0001 indicates that this picture is the first frame in this short video (tracklet). In each short video (tracklet), the number of frames starts from F0001.

1.3.2 test_name.txt

Similarly, in this txt file, the names of all pictures in the bbox_test folder are stored in order, with a total of 681,089 lines.

1.3.3 tracks_train_info.mat

The file in the .mat format is a file saved by matlab. After opening it with matlab, you can see that it is an 8298*4 matrix.
Each row of the matrix represents a tracklet; the
first and second columns represent the sequence number (start, end) of the picture, which corresponds to the row number in the train_name.txt file; the
third column is for pedestrians id, which is the name of the corresponding subfolder in the bbox_train folder;
the fourth column is the corresponding camera id (a total of 6 cameras).
Insert picture description hereInsert picture description herePay attention to comparing the two pictures~

1.3.4 tracks_train_info.mat

After opening this file with matlab, you can see that it is a 12180 * 4 matrix.
Each row of the matrix represents a tracklet; the
first and second columns represent the serial number of the picture, which corresponds to the row number in the test_name.txt file; the
third column is the id of the pedestrian, which is in the bbox_test folder The name of the corresponding subfolder;
the fourth column is the corresponding camera id (a total of 6 cameras).
Similar to the above~

1.3.5 query_IDX.mat

After opening this file with matlab, you can see that it is a 1 * 1980 matrix (choose 1980 query ids), and you can see that each column corresponds to the first few rows in the tracks_test_info.mat file above .
For example, the value in the 1978 column is 12177, which corresponds to line 12177 in the tracks_test_info.mat file (one line corresponds to one tracks).
In line 12177, you can see its id=1496 (pedestrian id). It is not difficult to find that the lines with the same id=1496 also have 12166, 12167, etc. (a pedestrian corresponds to multiple trajectories).
In fact, this means that in the subfolder named 1496 (the pedestrian id is 1496), there are multiple short videos (tracklets).
It is worth noting that not all query sets id, the gallery has a row corresponding to the pedestrian with the same id. Among the 1980 query ids, the number of valid ids (there are rows with the same id in the gallery) = 1840.
In other words, there is only 1 tracklet in some folders.

Insert picture description here

1.4 Summary

In general:

  • One training set corresponds to multiple pedestrian ids, one id corresponds to multiple tracks, and one track corresponds to multiple pictures.
  • There is no duplicate pedestrian id in training set and test level
  • The selected part of the test set is used as query

2.mars data set management data_manager

When introducing pedestrian re-recognition earlier, this part is also included. The purpose is to encapsulate the mars data set in the hard disk into the dataset.

Most of the methods are the same, just paste the code directly:

# 导入相关包
from __future__ import print_function, absolute_import
import os
import glob
import re
import sys
import urllib
import tarfile
import zipfile
import os.path as osp
from scipy.io import loadmat
import numpy as np
import random

from utils.util import mkdir_if_missing, write_json, read_json

"""Dataset classes"""

# 定义类方法 
class Mars(object):
    """
    MARS

    Reference:
    Zheng et al. MARS: A Video Benchmark for Large-Scale Person Re-identification. ECCV 2016.
    
    Dataset statistics:
    # identities: 1261
    # tracklets: 8298 (train) + 1980 (query) + 9330 (gallery)
    # cameras: 6

    Args:
        min_seq_len (int): tracklet with length shorter than this value will be discarded (default: 0).
    """
    # 设置mars路径 这个要根据自己文件夹中存放数据集的位置
    root = '/home/user/桌面/code/data/mars'
    # 读取对应文件夹路径
    train_name_path = osp.join(root, 'info/train_name.txt')
    test_name_path = osp.join(root, 'info/test_name.txt')
    track_train_info_path = osp.join(root, 'info/tracks_train_info.mat')
    track_test_info_path = osp.join(root, 'info/tracks_test_info.mat')
    query_IDX_path = osp.join(root, 'info/query_IDX.mat')
	
	# 初始化类方法
    def __init__(self, min_seq_len=0):
    	# 1 提高工程性 确保文件都存在 
        self._check_before_run()

        # 2 prepare meta data
        # 获得所有的训练集图片名字,放在train_names列表中;
        # 获取所有测试集图片名字,放在test_names 列表中。
        train_names = self._get_names(self.train_name_path)
        test_names = self._get_names(self.test_name_path)
        # 使用loadmat()函数读取.mat文件,它读取出来的data是字典格式的,通过['track_train_info']这个key,找到对应的value。获得的是一个数组格式数据。
        track_train = loadmat(self.track_train_info_path)['track_train_info'] # numpy.ndarray (8298, 4) 8298tracks  4:start、end、id、cid
        track_test = loadmat(self.track_test_info_path)['track_test_info'] # numpy.ndarray (12180, 4) 12180tracks  4:start、end、id、cid
        query_IDX = loadmat(self.query_IDX_path)['query_IDX'].squeeze() # numpy.ndarray (1980,) 
        # 查询集的行号减一,跟track_test中的行号索引保持一致。
        query_IDX -= 1 # index from 0
        # 根据 query_IDX行号索引,找到track_test中对应行的数据  numpy.ndarray (1980, 4)
        track_query = track_test[query_IDX,:]
        # 图库集的行号 = 原始的track_test行号 - query_IDX中包含的行号
        gallery_IDX = [i for i in range(track_test.shape[0]) if i not in query_IDX]
        # 根据图库集行号,在track_test中找到对应行的数据,numpy.ndarray (1980, 4)
        track_gallery = track_test[gallery_IDX,:]
		# 3 数据处理
        train, num_train_tracklets, num_train_pids, num_train_imgs = \
          self._process_data(train_names, track_train, home_dir='bbox_train', relabel=True, min_seq_len=min_seq_len)

        query, num_query_tracklets, num_query_pids, num_query_imgs = \
          self._process_data(test_names, track_query, home_dir='bbox_test', relabel=False, min_seq_len=min_seq_len)

        gallery, num_gallery_tracklets, num_gallery_pids, num_gallery_imgs = \
          self._process_data(test_names, track_gallery, home_dir='bbox_test', relabel=False, min_seq_len=min_seq_len)
		
        num_imgs_per_tracklet = num_train_imgs + num_query_imgs + num_gallery_imgs
        min_num = np.min(num_imgs_per_tracklet)
        max_num = np.max(num_imgs_per_tracklet)
        avg_num = np.mean(num_imgs_per_tracklet)

        num_total_pids = num_train_pids + num_query_pids
        num_total_tracklets = num_train_tracklets + num_query_tracklets + num_gallery_tracklets

        print("=> MARS loaded")
        print("Dataset statistics:")
        print("  ------------------------------")
        print("  subset   | # ids | # tracklets")
        print("  ------------------------------")
        print("  train    | {:5d} | {:8d}".format(num_train_pids, num_train_tracklets))
        print("  query    | {:5d} | {:8d}".format(num_query_pids, num_query_tracklets))
        print("  gallery  | {:5d} | {:8d}".format(num_gallery_pids, num_gallery_tracklets))
        print("  ------------------------------")
        print("  total    | {:5d} | {:8d}".format(num_total_pids, num_total_tracklets))
        print("  number of images per tracklet: {} ~ {}, average {:.1f}".format(min_num, max_num, avg_num))
        print("  ------------------------------")

        self.train = train
        self.query = query
        self.gallery = gallery

        self.num_train_pids = num_train_pids
        self.num_query_pids = num_query_pids
        self.num_gallery_pids = num_gallery_pids
        
	# 检验文件是否存在
    def _check_before_run(self):
        """Check if all files are available before going deeper"""
        if not osp.exists(self.root):
            raise RuntimeError("'{}' is not available".format(self.root))
        if not osp.exists(self.train_name_path):
            raise RuntimeError("'{}' is not available".format(self.train_name_path))
        if not osp.exists(self.test_name_path):
            raise RuntimeError("'{}' is not available".format(self.test_name_path))
        if not osp.exists(self.track_train_info_path):
            raise RuntimeError("'{}' is not available".format(self.track_train_info_path))
        if not osp.exists(self.track_test_info_path):
            raise RuntimeError("'{}' is not available".format(self.track_test_info_path))
        if not osp.exists(self.query_IDX_path):
            raise RuntimeError("'{}' is not available".format(self.query_IDX_path))

	# 获取txt文件中的字符串(图片名字),放在names列表中。
    def _get_names(self, fpath):
        names = []
        with open(fpath, 'r') as f:
            for line in f:
                new_line = line.rstrip()
                names.append(new_line)
        return names
        
	# 对获得的数据按照规则进行截断 获得tracklets, num_tracklets, num_pids, num_imgs_per_tracklet
    def _process_data(self, names, meta_data, home_dir=None, relabel=False, min_seq_len=0):
        assert home_dir in ['bbox_train', 'bbox_test']
        num_tracklets = meta_data.shape[0]
        pid_list = list(set(meta_data[:,2].tolist()))
        num_pids = len(pid_list)

        if relabel: pid2label = {
    
    pid:label for label, pid in enumerate(pid_list)}
        tracklets = []
        num_imgs_per_tracklet = []

        #txt_name = self.root + home_dir + str(len(meta_data)) + '.txt'
        #fid = open(txt_name, "w")

        for tracklet_idx in range(num_tracklets):
            data = meta_data[tracklet_idx,...]
            start_index, end_index, pid, camid = data
            if pid == -1: continue # junk images are just ignored
            assert 1 <= camid <= 6
            if relabel: pid = pid2label[pid]
            camid -= 1 # index starts from 0
            img_names = names[start_index-1:end_index]

            # make sure image names correspond to the same person
            pnames = [img_name[:4] for img_name in img_names]
            assert len(set(pnames)) == 1, "Error: a single tracklet contains different person images"

            # make sure all images are captured under the same camera
            camnames = [img_name[5] for img_name in img_names]
            assert len(set(camnames)) == 1, "Error: images are captured under different cameras!"

            # append image names with directory information
            img_paths = [osp.join(self.root, home_dir, img_name[:4], img_name) for img_name in img_names]
            if len(img_paths) >= min_seq_len:
                img_paths = tuple(img_paths)
                tracklets.append((img_paths, pid, camid))
                num_imgs_per_tracklet.append(len(img_paths))
                #fid.write(img_names[0] + '\n')
 
        #fid.close()
        num_tracklets = len(tracklets)

        return tracklets, num_tracklets, num_pids, num_imgs_per_tracklet

"""Create dataset"""

__factory = {
    
    
    'mars': Mars,
    'ilidsvid': iLIDSVID,
    'prid': PRID,
}

def get_names():
    return __factory.keys()

def init_dataset(name, *args, **kwargs):
    if name not in __factory.keys():
        raise KeyError("Unknown dataset: {}".format(name))
    return __factory[name](*args, **kwargs)

# test
if __name__ == '__main__':

    init_dataset(name="mars")
    #dataset = Market1501()
    #dataset = Mars()



Result:
Insert picture description hereExplanation:

  • Training set:
    • 625 ids, 8298 trajectories in total
  • Test set:
    • Query 626 id selected 1980 tracks (not all valid, a pedestrian may only have one track)
    • gallery 622 id, the remaining 9330 trajectories

A total of 1251 pedestrian ids, train+query, 8298+1980+9330=19608 trajectories

Guess you like

Origin blog.csdn.net/qq_37747189/article/details/115263678