Python实现mhd文件转dicom格式

问题提出

        最近我们遇到了一个问题。我们原计划在MRI图像堆栈上手动标注直肠癌的mask,以用于后续的影像组学研究。然而,手动标注耗时过多,因此我们打算基于开源模型的结果进行修改,最终得到可用的癌症病变区域标注。我们发现现有的直肠癌分割模型只接受mhd格式的输入,并输出mhd格式的文件,代表分割得到的灰度掩膜。然而,该模型在我们的数据集上效果欠佳,需要我们进行手动修改。但是,我没有找到可以修改mhd文件数据的标注软件(可能有,但我没找到)。因此,我们需要将mhd文件转换为dicom格式。

MHD与DICOM格式简介

MHD 格式

        MHD(MetaImage Header)是一种用于医学图像存储的文件格式。它通常与RAW数据文件配合使用,以提供图像数据的详细描述。

特点: 

文件结构:MHD文件包含图像数据的元数据,如维度、数据类型、像素间距等。与之配套的RAW文件则存储实际的图像数据。
灵活性:MHD文件可以描述任意维度的图像数据,适用于3D医学图像。
易读性:由于MHD文件是纯文本文件,易于阅读和修改。
应用:广泛用于医学图像处理和分析,特别是在研究和开发阶段。

示例:

ObjectType = Image
NDims = 3
DimSize = 256 256 128
ElementType = MET_UCHAR
ElementSpacing = 1.0 1.0 1.0
ElementDataFile = image.raw

DICOM 格式

        DICOM(Digital Imaging and Communications in Medicine)是医学成像领域的标准格式,用于存储、传输和处理医学图像。

特点:

综合性:DICOM文件不仅包含图像数据,还包括丰富的患者信息、扫描参数等元数据。
互操作性:作为标准格式,DICOM文件可以在不同的医学成像设备和软件之间无缝传输。
复杂性:DICOM格式较为复杂,包含大量的标准标签和数据元素。
广泛应用:广泛应用于医院、诊所等医疗机构,用于CT、MRI、X光等多种医学成像设备。

示例:

DICOM文件通常包含一个头部和图像数据部分。头部包括患者信息、图像获取参数等,例如:
(0008, 0020) Study Date
(0010, 0010) Patient's Name
(0020, 0013) Image Number

对比总结

MHD文件简单、灵活,适合研究和开发环境。
DICOM文件复杂、综合性强,是医学成像的行业标准,适用于临床环境。

MHD转DICOM

代码如下:

import os
import numpy as np
import SimpleITK as sitk
import pydicom
from pydicom.dataset import Dataset, FileDataset
from pydicom.uid import generate_uid
def convert_mhd_to_dicom(mhd_file_path, dicom_output_dir):
    if not os.path.exists(dicom_output_dir):
        os.makedirs(dicom_output_dir)

    series_instance_uid = generate_uid()
    study_instance_uid = generate_uid()

    # Read the MHD image
    image = sitk.ReadImage(mhd_file_path)
    image_array = sitk.GetArrayFromImage(image)

    # Get metadata
    spacing = image.GetSpacing()
    origin = image.GetOrigin()
    direction = image.GetDirection()

    # Iterate over each slice and save it as a DICOM file
    for i in range(image_array.shape[0]):
        slice_array = image_array[i, :, :]
        slice_array = slice_array.astype(np.uint8)

        # Create DICOM dataset
        file_meta = pydicom.dataset.FileMetaDataset()
        file_meta.MediaStorageSOPClassUID = pydicom.uid.MRImageStorage
        file_meta.MediaStorageSOPInstanceUID = generate_uid()
        file_meta.TransferSyntaxUID = pydicom.uid.ExplicitVRLittleEndian

        ds = FileDataset(None, {}, file_meta=file_meta, preamble=b"\0" * 128)

        # Set necessary values for the DICOM dataset
        ds.PatientName = "0001"
        ds.PatientID = "0001"
        ds.Modality = "MR"
        ds.ContentDate = "20240101"
        ds.ContentTime = "120000"
        ds.StudyInstanceUID = study_instance_uid
        ds.SeriesInstanceUID = series_instance_uid
        ds.SOPInstanceUID = file_meta.MediaStorageSOPInstanceUID
        ds.SOPClassUID = file_meta.MediaStorageSOPClassUID

        # Set pixel data
        ds.is_little_endian = True
        ds.is_implicit_VR = False
        ds.PixelData = slice_array.tobytes()

        # Set additional metadata
        ds.Rows, ds.Columns = slice_array.shape
        ds.BitsAllocated = 8
        ds.BitsStored = 8
        ds.HighBit = 7
        ds.PixelRepresentation = 0
        ds.SamplesPerPixel = 1
        ds.PhotometricInterpretation = "MONOCHROME2"
        ds.PixelSpacing = [str(spacing[0]), str(spacing[1])]
        ds.SpacingBetweenSlices = str(spacing[2])
        ds.SliceThickness = str(spacing[2])
        ds.ImagePositionPatient = [str(origin[0]), str(origin[1]), str(origin[2] + i * spacing[2])]
        ds.ImageOrientationPatient = [str(direction[0]), str(direction[1]), str(direction[2]),
                                      str(direction[3]), str(direction[4]), str(direction[5])]

        # Save the DICOM file
        dicom_file_path = os.path.join(dicom_output_dir, f"slice_{i:04d}.dcm")
        ds.save_as(dicom_file_path)
        print(f"Saved {dicom_file_path}")


convert_mhd_to_dicom('E:/ptj/3D-RU-Net-master/Output/0001/EnsemblePreds.mhd',
                    'E:/ptj/3D-RU-Net-master/Output/0001/dicom')

目录结构如下:

总体来说,输入mhd文件路径,在dicom文件夹中输出若干dicom格式的文件堆栈,需要注意的是ds.SliceThickness 可能需要根据实际情况经行修改。

结尾

医工结合是未来的发展趋势。我们深知一线临床医疗人员的辛苦与挑战。如果您是一名临床医生,并在科研上遇到问题,可以随时与我联系。

  • 6
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值