如何对固定长度时序图像序列样本执行数据增强及代码实现
固定间隔时序图像序列增强实现
注意:时序图像增强的核心原则是同一样本内的所有帧必须共享完全一致的变换参数,禁止对单帧独立做随机增强,否则会破坏序列帧之间的空间对应关系,引入无效噪声。
基础信息匹配
- 原始样本量:17个,单样本包含30张112*112尺寸的3通道图像,整体张量形状
(17, 30, 112, 112, 3) - 目标样本量:50个,增强后张量形状保持
(50, 30, 112, 112, 3) - 原始数据存储结构:根目录下包含
folder_1至folder_17共17个独立文件夹,每个文件夹内存放对应样本的30张序列图像
采用的时序安全增强策略
所有增强操作对同一样本的30张帧统一生成随机参数、统一施加变换:
- 空间变换:随机水平翻转(概率0.5)、±15°范围内随机旋转、±10%图像尺寸范围内随机平移、0.9-1.1倍范围内随机缩放
- 像素调整:±0.1幅度范围内随机亮度调整、±0.1幅度范围内随机对比度调整
- 不使用帧顺序打乱、单帧独立随机变换类操作,避免破坏3秒间隔采集序列的时序关联性
可直接运行的实现代码
import os import cv2 import numpy as np from glob import glob # -------------------------- 配置参数 -------------------------- ROOT_DIR = "./your_dataset_root" # 替换为存放folder_1到folder_17的根目录路径 TARGET_SAMPLE_NUM = 50 IMG_HEIGHT, IMG_WIDTH = 112, 112 SEQ_LEN = 30 # 增强参数范围 ROTATE_RANGE = 15 SHIFT_RANGE = 0.1 SCALE_RANGE = (0.9, 1.1) FLIP_PROB = 0.5 BRIGHTNESS_RANGE = 0.1 CONTRAST_RANGE = 0.1 # -------------------------- 工具函数 -------------------------- def load_single_sample(folder_path): """加载单个文件夹内的30张序列图像,返回形状为(30,112,112,3)的数组,像素值归一化到0-1""" img_paths = sorted(glob(os.path.join(folder_path, "*")))[:SEQ_LEN] seq = [] for p in img_paths: img = cv2.imread(p) img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) img = cv2.resize(img, (IMG_WIDTH, IMG_HEIGHT)) seq.append(img / 255.0) return np.array(seq, dtype=np.float32) def augment_single_seq(seq): """对输入的单条序列(30,112,112,3)施加统一参数的增强,返回增强后的序列""" h, w = IMG_HEIGHT, IMG_WIDTH # 生成统一的空间变换参数 angle = np.random.uniform(-ROTATE_RANGE, ROTATE_RANGE) tx = np.random.uniform(-SHIFT_RANGE, SHIFT_RANGE) * w ty = np.random.uniform(-SHIFT_RANGE, SHIFT_RANGE) * h scale = np.random.uniform(SCALE_RANGE[0], SCALE_RANGE[1]) flip = np.random.random() < FLIP_PROB # 计算仿射变换矩阵 center = (w//2, h//2) M = cv2.getRotationMatrix2D(center, angle, scale) M[0, 2] += tx M[1, 2] += ty # 生成统一的像素调整参数 alpha = 1 + np.random.uniform(-CONTRAST_RANGE, CONTRAST_RANGE) # 对比度系数 beta = np.random.uniform(-BRIGHTNESS_RANGE, BRIGHTNESS_RANGE) # 亮度偏移 aug_seq = [] for frame in seq: # 施加空间变换 aug_frame = cv2.warpAffine(frame, M, (w, h), borderMode=cv2.BORDER_REFLECT) # 施加像素调整 aug_frame = np.clip(alpha * aug_frame + beta, 0, 1) # 施加翻转 if flip: aug_frame = cv2.flip(aug_frame, 1) aug_seq.append(aug_frame) return np.array(aug_seq, dtype=np.float32) # -------------------------- 主流程 -------------------------- if __name__ == "__main__": # 加载所有原始样本 raw_samples = [] for i in range(1, 18): folder_path = os.path.join(ROOT_DIR, f"folder_{i}") raw_samples.append(load_single_sample(folder_path)) raw_samples = np.array(raw_samples) print(f"原始数据集形状:{raw_samples.shape}") # 初始化增强数据集,先放入所有原始样本 aug_dataset = list(raw_samples) # 循环生成增强样本直到达到目标数量 while len(aug_dataset) < TARGET_SAMPLE_NUM: # 随机选一个原始样本做增强 sample_idx = np.random.randint(0, len(raw_samples)) selected_seq = raw_samples[sample_idx] aug_seq = augment_single_seq(selected_seq) aug_dataset.append(aug_seq) # 截断到目标数量,转为数组 aug_dataset = np.array(aug_dataset[:TARGET_SAMPLE_NUM]) print(f"增强后数据集形状:{aug_dataset.shape}") # 保存增强后的数据集 np.save(os.path.join(ROOT_DIR, "augmented_seq_dataset.npy"), aug_dataset)
使用说明
- 运行前将代码中
ROOT_DIR变量替换为实际存放folder_1到folder_17的根目录路径 - 代码默认将增强后的数据集保存为根目录下的
augmented_seq_dataset.npy文件,可直接加载用于模型训练 - 若需要调整增强强度,可直接修改开头配置参数段的对应范围值,不建议将空间变换参数范围设置过大,避免引入失真样本
内容的提问来源于stack exchange,提问作者Prathap David Carlo
相关产品推荐
相关产品推荐

