验证数据集构建的策略
七崽爱吃小饼干2025/09/12阅读 1
今天的任务主要聚焦于如何从SYSU- MM01数据集中抽取合适的样本,用于标注语义分割掩码,最后用于验证语义分割模型在行人重识别域上的泛化能力。
-
数量上:从rgb图像和ir图像中各抽取200张,共计400张图片。
-
抽取策略:尽量把每个cam下的不同id都覆盖到,室内和室外样本都要涉及,也要注意覆盖人的各种姿势(正面、侧面、背面)。
- 一共有6个cam,4个rgb cam(1、2、4、5),2个ir cam(3、6),每个cam下有300-500个id。
- cam1、2、3是室内模式,cam4、5、6是室外模式
- 每个rgb相机下抽取50张照片,每个相机下随机抽取50个id,每个id抽取一张,共计200张。
- 每个ir相机下抽取100张照片,每个相机想随机抽取100个id,每个id抽取一张,共计200张。
-
测评策略:分别计算ir、rgb图片的mIOU以及总体的mIOU
样本抽取脚本
python
import os
import random
import shutil
from collections import defaultdict
def parse_sysu_mm01_structure(data_root):
"""
解析SYSU-MM01数据集结构,按相机和ID分类
:param data_root: 数据集根目录
:return: 结构为 {相机号: {ID: [图像路径列表]}} 的字典
"""
# 定义相机类型和场景属性
cam_info = {
1: {'type': 'rgb', 'scene': 'indoor'},
2: {'type': 'rgb', 'scene': 'indoor'},
3: {'type': 'ir', 'scene': 'indoor'},
4: {'type': 'rgb', 'scene': 'outdoor'},
5: {'type': 'rgb', 'scene': 'outdoor'},
6: {'type': 'ir', 'scene': 'outdoor'}
}
# 初始化数据结构
cam_dict = defaultdict(lambda: defaultdict(list)) # cam -> id -> [img_paths]
# 遍历数据集目录
for cam in cam_info.keys():
cam_dir = os.path.join(data_root, f'cam{cam}')
if not os.path.exists(cam_dir):
print(f"警告: 相机目录 {cam_dir} 不存在")
continue
# 遍历每个ID目录
for id_folder in os.listdir(cam_dir):
id_path = os.path.join(cam_dir, id_folder)
if not os.path.isdir(id_path):
continue
# 收集该ID下的所有图像
for img_file in os.listdir(id_path):
if img_file.endswith(('.jpg', '.png')): # 假设图像格式为jpg或png
img_path = os.path.join(id_path, img_file)
cam_dict[cam][id_folder].append(img_path)
return cam_dict, cam_info
def select_samples(cam_dict, cam_info, output_dir):
"""
按照指定策略抽取样本
"""
# 创建输出目录
os.makedirs(output_dir, exist_ok=True)
os.makedirs(os.path.join(output_dir, 'rgb'), exist_ok=True)
os.makedirs(os.path.join(output_dir, 'ir'), exist_ok=True)
# 记录抽取信息
selection_log = []
# 处理RGB相机 (1,2,4,5) - 每个相机抽取50个ID,每个ID1张
rgb_cams = [1, 2, 4, 5]
for cam in rgb_cams:
cam_id_dict = cam_dict.get(cam, {})
if not cam_id_dict:
print(f"警告: 相机 {cam} 没有找到数据")
continue
# 随机选择50个ID (如果ID数量不足50则全部选择)
selected_ids = random.sample(list(cam_id_dict.keys()), min(50, len(cam_id_dict)))
for idx, person_id in enumerate(selected_ids):
# 从该ID中随机选择一张图像
img_paths = cam_id_dict[person_id]
selected_img = random.choice(img_paths)
# 复制图像到输出目录
dest_path = os.path.join(output_dir, 'rgb',
f'cam{cam}_id{person_id}_{os.path.basename(selected_img)}')
shutil.copy2(selected_img, dest_path)
# 记录选择信息
selection_log.append({
'type': 'rgb',
'cam': cam,
'scene': cam_info[cam]['scene'],
'person_id': person_id,
'src': selected_img,
'dest': dest_path
})
print(f"已抽取 RGB 图像: 相机{cam} ID{person_id} ({idx+1}/50)")
# 处理IR相机 (3,6) - 每个相机抽取100个ID,每个ID1张
ir_cams = [3, 6]
for cam in ir_cams:
cam_id_dict = cam_dict.get(cam, {})
if not cam_id_dict:
print(f"警告: 相机 {cam} 没有找到数据")
continue
# 随机选择100个ID (如果ID数量不足100则全部选择)
selected_ids = random.sample(list(cam_id_dict.keys()), min(100, len(cam_id_dict)))
for idx, person_id in enumerate(selected_ids):
# 从该ID中随机选择一张图像
img_paths = cam_id_dict[person_id]
selected_img = random.choice(img_paths)
# 复制图像到输出目录
dest_path = os.path.join(output_dir, 'ir',
f'cam{cam}_id{person_id}_{os.path.basename(selected_img)}')
shutil.copy2(selected_img, dest_path)
# 记录选择信息
selection_log.append({
'type': 'ir',
'cam': cam,
'scene': cam_info[cam]['scene'],
'person_id': person_id,
'src': selected_img,
'dest': dest_path
})
print(f"已抽取 IR 图像: 相机{cam} ID{person_id} ({idx+1}/100)")
# 保存抽取日志
with open(os.path.join(output_dir, 'selection_log.txt'), 'w') as f:
for entry in selection_log:
f.write(f"{entry['type']} | 相机{entry['cam']}({entry['scene']}) | ID{entry['person_id']} | 来源: {entry['src']}\n")
print(f"\n抽取完成! 共抽取 {len(selection_log)} 张图像")
print(f"输出目录: {output_dir}")
print(f"抽取日志: {os.path.join(output_dir, 'selection_log.txt')}")
if __name__ == "__main__":
# 配置路径
DATA_ROOT = "/path/to/sysu-mm01" # 替换为你的SYSU-MM01数据集根目录
OUTPUT_DIR = "./selected_samples" # 输出目录
# 解析数据集结构
print("正在解析数据集结构...")
cam_dict, cam_info = parse_sysu_mm01_structure(DATA_ROOT)
# 抽取样本
print("\n开始抽取样本...")
select_samples(cam_dict, cam_info, OUTPUT_DIR)