std::vector inp_raw; // 补充:OPENAI_CLIP的均值和标准差(来自图2,对应RGB通道) const std::vector OPENAI_CLIP_MEAN = {0.48145466f, 0.4578275f, 0.40821073f}; const std::vector OPENAI_CLIP_STD = {0.26862954f, 0.26130258f, 0.27577711f}; // set input pixel values if (!imgs.is_audio) { size_t nelem = 0; for (const auto & img : imgs.entries) { nelem += img->nx * img->ny * 3; // 总元素数=图片数×宽×高×3通道 } inp_raw.resize(nelem); // 预分配内存 for (size_t i = 0; i < imgs.entries.size(); i++) { const int nx = imgs.entries[i]->nx; // 图像宽度 const int ny = imgs.entries[i]->ny; // 图像高度 const int n = nx * ny; // 单通道像素总数(宽×高) for (int b = 0; b < batch_size; b++) { // 遍历批次(假设batch_size ≤ 图片数) // 当前样本在inp_raw中的起始地址(3通道,每通道n像素) float* batch_entry = inp_raw.data() + b * (3 * n); for (int y = 0; y < ny; y++) { // 遍历行 for (int x = 0; x < nx; x++) { // 遍历列 // 源图像中当前像素的RGB起始索引(假设buf按RGB顺序存储) size_t base_src = 3 * (y * nx + x); // 目标通道内的像素索引(行优先,同原代码) size_t base_dst = y * nx + x; // -------------------------- 核心:缩放+标准化 -------------------------- // 1. 读取原始RGB值(假设buf为0-255的整数,转为float) float r = static_cast(imgs.entries[b]->buf[base_src]); // R通道 float g = static_cast(imgs.entries[b]->buf[base_src + 1]); // G通道 float b_val = static_cast(imgs.entries[b]->buf[base_src + 2]); // B通道(避名) // 2. 缩放:×1/255(归一化到0-1) r *= (1.0f / 255.0f); g *= (1.0f / 255.0f); b_val *= (1.0f / 255.0f); // 3. 标准化:(x - mean) / std(使用CLIP的均值和标准差) r = (r - OPENAI_CLIP_MEAN[0]) / OPENAI_CLIP_STD[0]; // R通道标准化 g = (g - OPENAI_CLIP_MEAN[1]) / OPENAI_CLIP_STD[1]; // G通道标准化 b_val = (b_val - OPENAI_CLIP_MEAN[2]) / OPENAI_CLIP_STD[2]; // B通道标准化 // ---------------------------------------------------------------------- // 存入batch_entry(通道顺序:R→0~n-1,G→n~2n-1,B→2n~3n-1,与原代码一致) batch_entry[base_dst] = r; // R通道 batch_entry[1 * n + base_dst] = g; // G通道(1×n偏移) batch_entry[2 * n + base_dst] = b_val; // B通道(2×n偏移) } } } } }