deep-person-reid训练自定义模型
- 1. 准备代码
 - 2. market1501格式
 - 3 转换格式代码
 - 4. 训练
 - 5 追踪测试
 
仅供参考,目前实现的格式转化还是存在一定的问题,导致训练后的模型精度很高,分配上还是没有完全符合market1501的格式。依照这样训练的模型,效果还可以,
1. 准备代码
- yolov5追踪代码

 - deep-person-reid代码
 
git clone https://github.com/KaiyangZhou/deep-person-reid.git
 
2. market1501格式
目录介绍
 1) “bounding_box_test”——用于测试集的 750 人,包含 19,732 张图像,前缀为 0000 表示在提取这 750 人的过程中DPM检测错的图(可能与query是同一个人),-1 表示检测出来其他人的图(不在这 750 人中)
 2) “bounding_box_train”——用于训练集的 751 人,包含 12,936 张图像
 3) “query”——为 750 人在每个摄像头中随机选择一张图像作为query,因此一个人的query最多有 6 个,共有 3,368 张图像
 4) “gt_query”——matlab格式,用于判断一个query的哪些图片是好的匹配(同一个人不同摄像头的图像)和不好的匹配(同一个人同一个摄像头的图像或非同一个人的图像)
 5) “gt_bbox”——手工标注的bounding box,用于判断DPM检测的bounding box是不是一个好的box
 命名规则
 以 0001_c1s1_000151_01.jpg 为例
 1) 0001 表示每个人的标签编号,从0001到1501;
 2) c1 表示第一个摄像头(camera1),共有6个摄像头;
 3) s1 表示第一个录像片段(sequece1),每个摄像机都有数个录像段;
 4) 000151 表示 c1s1 的第000151帧图片,视频帧率25fps;
 5) 01 表示 c1s1_001051 这一帧上的第1个检测框,由于采用DPM检测器,对于每一帧上的行人可能会框出好几个bbox。00 表示手工标注框
3 转换格式代码
import os
import shutil
import random
# 输入数据文件夹
input_pedestrian_folder = r"F:\sjh\code\deep-person-reid\reid-data\my_data\person"
input_vehicle_folder = r"F:\sjh\code\deep-person-reid\reid-data\my_data\car"
# 输出数据文件夹
output_root = r"F:\sjh\code\deep-person-reid\reid-data\my_data/Market1501"
bounding_box_train = os.path.join(output_root, "bounding_box_train")
bounding_box_test = os.path.join(output_root, "bounding_box_test")
query = os.path.join(output_root, "query")
if os.path.exists(bounding_box_train):
    shutil.rmtree(bounding_box_train)
    shutil.rmtree(bounding_box_test)
    shutil.rmtree(query)
os.makedirs(bounding_box_train, exist_ok=True)
os.makedirs(bounding_box_test, exist_ok=True)
os.makedirs(query, exist_ok=True)
def rename_and_split_images(input_folder, pid_start, camid, query_bool=False,classes=0):
    pid = pid_start
    image_files = os.listdir(input_folder)
    frame = 1
    for image_file in image_files:
        # 为每个行人/车辆分配一个唯一的pid
        # pid += 1
        # if classes == 1:
        #     pid = 1
        # elif classes == 2:
        #     pid = 2
        src_path = os.path.join(input_folder, image_file)
        # 在这里,我们假设每个输入文件夹只有一个摄像头和连续的帧
        frame += 1
        new_image_name = f"{pid:04d}_c{camid}s{camid}_{frame:06d}.jpg"
        dest_path = os.path.join(bounding_box_train, new_image_name)
        shutil.copyfile(src_path, dest_path)
        # 随机选择一些图像分配给bounding_box_test和query
        if random.random() < 0.1:
            frame += 1
            new_image_name = f"{pid:04d}_c{camid}s{camid}_{frame:06d}.jpg"
            dest_path = os.path.join(bounding_box_test, new_image_name)
            shutil.copyfile(src_path, dest_path)
            frame += 1
            if query_bool:
                camid=2
            new_image_name = f"{pid:04d}_c{camid}s{camid}_{frame:06d}.jpg"
            dest_path = os.path.join(query, new_image_name)
            shutil.copyfile(src_path, dest_path)
    return pid
# 处理行人数据
last_pid = rename_and_split_images(input_pedestrian_folder, 0, 1,query_bool=True,classes=1)
# 处理车辆数据
rename_and_split_images(input_vehicle_folder, 1, 2, query_bool=True,classes=2)
 
数据存放位置,最后会生成market1501,用于训练的三个文件train、test、query:
 
 
 代码命名规则:
 0000_c1s1_000002.jpg
- 0000 表示种类人,0001表示车辆种类
 - c1s1表示摄像机和录像片段,全部为1即可,但是query里全部设为了c2s2。
 - 000002表示帧数,每类的所有照片按照不同帧数划分
 
4. 训练
新建一个train.py文件
import torchreid
if __name__ == '__main__':
    datamanager = torchreid.data.ImageDataManager(
        root="reid-data",#/market1501
        sources="market1501",
        targets="market1501",
        height=256,
        width=128,
        batch_size_train=36,
        batch_size_test=1,
        transforms=["random_flip", "random_crop"]
    )
    model = torchreid.models.build_model(
        name="resnet50",
        num_classes=datamanager.num_train_pids,
        loss="softmax",
        pretrained=True
    )
    model = model.cuda()
    optimizer = torchreid.optim.build_optimizer(
        model,
        optim="adam",
        lr=0.0003
    )
    scheduler = torchreid.optim.build_lr_scheduler(
        optimizer,
        lr_scheduler="single_step",
        stepsize=20
    )
    engine = torchreid.engine.ImageSoftmaxEngine(
        datamanager,
        model,
        optimizer=optimizer,
        scheduler=scheduler,
        label_smooth=True
    )
    engine.run(
        save_dir="log/resnet50",
        max_epoch=20,
        eval_freq=1,
        print_freq=1,
        test_only=False
    )
 
训练后会得到一个追踪模型,基于resnet50
 
5 追踪测试
- 将训练后的追踪模型放到追踪代码目录下,并命名为weights/resnet50_market1501.pt。
 - 下载追踪代码后,修改参数如下
 
parser.add_argument('--yolo-weights', nargs='+', type=Path, default=WEIGHTS / 'yolov5s.pt', help='model.pt path(s)')
parser.add_argument('--reid-weights', type=Path, default=WEIGHTS / 'resnet50_market1501.pt')
parser.add_argument('--tracking-method', type=str, default='bytetrack', help='strongsort, ocsort, bytetrack')#bytetrack最快,效果也比较好
 



















