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

如何使用Python裁剪mhd格式MR三维影像并保存为新mhd文件

非正方形画幅MR mhd影像裁剪落地方案

核心逻辑:mhd格式为「头文件(.mhd)+裸数据(.raw)」的配对存储结构,裁剪操作不需要依赖原始DICOM文件,仅需完成体数据截取、空间几何参数校正、元数据映射三个核心步骤,最后重新生成配对的mhd/raw文件即可。

实现步骤

  • 环境准备:安装SimpleITK、numpy、json三个依赖库,所有操作直接在本地完成,不需要上传数据。
  • 原始数据读取:调用SimpleITK的ReadImage()接口直接读入原始.mhd文件,接口会自动关联同目录下同名.raw文件,读入后可直接获取原始体数据、像素间距(Spacing)、影像原点(Origin)、方向矩阵(Direction)四类核心空间参数,读入时不要做任何重采样操作,保持原始非正方形画幅的像素精度。

    注意:调用GetArrayFromImage()转numpy数组时,维度顺序为[z轴(层方向), y轴, x轴],和mhd头文件中记录的x/y/z顺序相反,后续裁剪操作不要写反索引。

  • 裁剪范围确定与体数据截取:明确三个维度的保留区间,x/y为画幅所在平面维度,z为层扫维度,按像素索引直接截取numpy数组对应区间即可,全程不要做插值操作,避免改变原始MR信号值。记录裁剪后三个维度的像素总数,后续更新头文件使用。
  • 空间参数校正:裁剪操作不会改变像素间距、方向矩阵,这两个参数直接沿用原始值即可;原点坐标需要根据裁剪起始索引重新计算,避免保存后影像空间位置错位:
    新原点x值 = 原始原点x值 + x轴裁剪起始索引 * x轴像素间距
    新原点y值 = 原始原点y值 + y轴裁剪起始索引 * y轴像素间距
    新原点z值 = 原始原点z值 + z轴裁剪起始索引 * z轴像素间距
  • DICOM元数据映射:加载存储了全量原始DICOM头信息的json文件,将患者信息、扫描参数(TR/TE/层厚等)、序列信息等字段,直接作为元数据键值对写入新的影像对象;注意跳过DimSize/Origin/Spacing/ElementDataFile这类和裁剪后参数强相关的字段,避免旧值覆盖新计算的参数。
  • 结果保存:将裁剪后的数组、校正后的空间参数、映射完成的元数据绑定到影像对象,调用WriteImage()接口指定输出后缀为.mhd,接口会自动生成配对的.raw文件。

参考实现代码

import SimpleITK as sitk
import numpy as np
import json

# 读入原始mhd数据
raw_img = sitk.ReadImage("original_mr.mhd")
raw_array = sitk.GetArrayFromImage(raw_img)
depth, height, width = raw_array.shape  # 对应z,y,x维度

# 按需修改裁剪范围 示例为x轴左右各裁20像素,y轴上下各裁30像素,z轴全保留
x_start, x_end = 20, width - 20
y_start, y_end = 30, height - 30
z_start, z_end = 0, depth

# 执行数组裁剪
cropped_array = raw_array[z_start:z_end, y_start:y_end, x_start:x_end]

# 构建新影像对象 写入空间参数
cropped_img = sitk.GetImageFromArray(cropped_array)
cropped_img.SetSpacing(raw_img.GetSpacing())
new_origin = (
    raw_img.GetOrigin()[0] + x_start * raw_img.GetSpacing()[0],
    raw_img.GetOrigin()[1] + y_start * raw_img.GetSpacing()[1],
    raw_img.GetOrigin()[2] + z_start * raw_img.GetSpacing()[2]
)
cropped_img.SetOrigin(new_origin)
cropped_img.SetDirection(raw_img.GetDirection())

# 写入json存储的DICOM元数据
with open("dicom_header.json", "r", encoding="utf-8") as f:
    dicom_meta = json.load(f)
skip_keys = {"DimSize", "Origin", "Spacing", "Direction", "ElementDataFile", "ElementNumberOfChannels"}
for meta_key, meta_val in dicom_meta.items():
    if meta_key not in skip_keys:
        cropped_img.SetMetaData(meta_key, str(meta_val))

# 保存结果
sitk.WriteImage(cropped_img, "cropped_mr.mhd")

结果校验要点

  • 重新读入保存后的mhd文件,检查三个维度的像素数是否和裁剪目标一致,非正方形画幅是否符合预期
  • 选取3个以上固定解剖标记点,对比原始影像和裁剪后影像的空间坐标,确认无位置偏移
  • 抽查TR、TE、患者ID、序列名这类核心元数据,确认和json中存储的原始DICOM信息一致

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 13:48:14