You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用COBRE数据集Nifti文件构建CNN模型?

COBRE脑MRI数据集适配CNN输入实操方案

1. 批量Nifti文件加载、转模型输入格式方法

很多人对Nilearn的功能有误解:nilearn.image.load_img()并非仅支持单文件加载,传入文件路径列表即可批量读取Nifti数据,完全可以满足100例样本的批量处理需求。
具体处理流程如下:

  • 第一步:遍历数据集根目录,收集所有.nii文件的完整路径,存为排序后的路径列表,保证后续处理顺序和标签顺序对齐
  • 第二步:统一做预处理,所有样本必须用完全一致的预处理参数,否则会出现空间不对齐、分布偏移的问题:
    • 所有图像配准到MNI152标准模板
    • 重采样到相同的空间分辨率与尺寸
    • 做颅骨剥离,去除非脑组织的背景区域
    • 做信号强度归一化(z-score标准化或者缩放到0~1区间)
  • 第三步:根据你用的CNN类型转成对应输入格式:
    • 用3D CNN:预处理完的3D脑体积直接补一个通道维度,最终所有样本拼成形状为(样本数, 通道数, x, y, z)的张量即可输入
    • 用2D CNN:按统一规则切分2D切片后,拼成形状为(切片样本数, 通道数, x, y)的张量即可
  • 存储建议:100例样本的数据量不大,预处理完可以直接存为.npy或者.h5格式,训练时直接加载即可;如果后续要扩容数据集,可以直接写PyTorch/TensorFlow的自定义Dataset类,在线读取+预处理,不用一次性把所有数据读进内存。

批量处理参考代码:

import os
import glob
import numpy as np
import pandas as pd
from nilearn import image, datasets

# 加载标准MNI152模板作为配准参考
target_template = datasets.load_mni152_template()

# 收集所有nii文件路径
nii_root = "./cobre_raw"  # 替换为你的数据集存储路径
file_list = sorted(glob.glob(os.path.join(nii_root, "**/*.nii"), recursive=True))

all_img_arr = []
for file_path in file_list:
    # 加载单例图像
    img = image.load_img(file_path)
    # 配准重采样到标准模板空间
    resampled_img = image.resample_to_img(img, target_template, interpolation="continuous")
    # 转numpy数组
    img_arr = resampled_img.get_fdata()
    # 强度z-score归一化
    img_arr = (img_arr - img_arr.mean()) / img_arr.std()
    all_img_arr.append(img_arr)

# 拼接为(样本数, x, y, z)格式的数组,后续按需加通道维度
all_data = np.stack(all_img_arr, axis=0)

2. 切片选取规则

不需要默认只选中间位置的单张切片,切片选择完全匹配你的任务类型即可,核心原则是所有样本必须用完全一致的切片索引规则:

  • 首先先过滤无效切片:每个Nifti文件首尾的切片大多是无脑组织的纯背景,你可以遍历每个切片的非零像素占比,把占比低于阈值(比如<10%)的切片直接排除,剩下的就是包含有效脑组织的切片区间,150张原始切片一般能筛出80~100张有效切片。
  • 如果用2D CNN做疾病分类,三种常用选法:
    • 计算资源有限时:选取有效区间内覆盖研究相关核心脑区的10~20张切片(比如COBRE是精神分裂症数据集,优先选覆盖颞叶、海马、前额叶的切片),不要只选1张中间切片,单张切片包含的信息太少,模型极易过拟合
    • 追求效果时:把所有有效切片都作为独立训练样本,每个切片继承对应受试者的标签,训练时做切片级分类,推理时把同一个受试者所有切片的预测结果做多数投票,得到最终的受试者级分类结果,效果远好于单切片输入
    • 如果是特定脑区的针对性研究:直接选取对应脑区所在的切片位置即可
  • 如果用3D CNN:不需要单独选切片,把预处理完的3D脑体积裁掉边缘全零区域后,缩放到模型要求的固定输入尺寸(比如64×64×64、128×128×128)即可输入,能保留全部空间信息。

有效切片筛选参考代码:

def get_valid_slices(img_arr, threshold=0.1):
    valid_z_idx = []
    z_total = img_arr.shape[-1]
    for z in range(z_total):
        slice_data = img_arr[:, :, z]
        valid_ratio = np.count_nonzero(slice_data) / slice_data.size
        if valid_ratio > threshold:
            valid_z_idx.append(z)
    return valid_z_idx[0], valid_z_idx[-1] # 返回有效切片的起止索引,所有样本统一用这个区间

3. 标签配置方法

mask文件仅用于脑区分割、ROI信号提取等任务,和分类标签的配置完全无关,不需要依赖mask打标签。
标签配置的具体方法:

  • COBRE是公开的精神分裂症数据集,每个受试者的诊断标签(健康对照/精神分裂症患者)在数据集配套的元数据文件里已经给出,你只需要把Nifti文件名里的受试者ID提取出来,和元数据里的ID做匹配,就能拿到每个文件对应的标签。
  • 非常推荐用CSV文件存储路径-标签映射关系,CSV只需要两列:
    • file_path:存储每个.nii文件的完整绝对路径
    • label:存储对应标签,比如健康对照标0,患者标1
      后续不管做预处理还是写数据集加载逻辑,直接读取这个CSV就能拿到对应关系,不会出现标签错配的问题。

标签CSV生成参考代码:

# 提前整理元数据里的受试者ID-标签对应关系,示例如下
id_label_map = {
    "sub0001": 0,
    "sub0002": 1,
    # 补全所有受试者的对应关系即可
}

csv_records = []
for file_path in file_list:
    # 从文件名提取受试者ID,根据你自己的文件名命名规则调整截取逻辑
    file_name = os.path.basename(file_path)
    sub_id = file_name.split("_")[0]
    csv_records.append({
        "file_path": file_path,
        "label": id_label_map[sub_id]
    })

# 存储为CSV文件
pd.DataFrame(csv_records).to_csv("./cobre_label_map.csv", index=False)

推荐学习资源

  • Nilearn官方文档中的神经影像机器学习章节,包含批量处理、特征提取、模型训练的完整流程示例,不要仅参考单文件可视化部分的内容
  • 你所用深度学习框架(PyTorch/TensorFlow)的自定义Dataset实现教程,掌握自定义数据加载逻辑后可以适配任意格式的数据集
  • 开源的3D CNN脑疾病分类实操项目,重点参考其数据加载、预处理部分的实现逻辑,不需要从零开始踩坑

内容的提问来源于stack exchange,提问作者Ashima Tyagi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.31 13:09:16