Python 中正确裁剪并保存 DICOM 图像的完整教程

雨宇小哥_5394

雨宇小哥_5394

2026-11-04

303人浏览

原创

Python 中正确裁剪并保存 DICOM 图像的完整教程

本文详解如何使用 pydicom 和 OpenCV 安全裁剪单帧或多帧 DICOM 文件的像素区域,并保留原始元数据与符合标准的 Pixel Data 结构,最终生成可被 ITK-SNAP、3D Slicer 等医学图像工具正常读取的合规 .dcm 文件。

本文详解如何使用 pydicom 和 opencv 安全裁剪单帧或多帧 dicom 文件的像素区域,并保留原始元数据与符合标准的 pixel data 结构,最终生成可被 itk-snap、3d slicer 等医学图像工具正常读取的合规 `.dcm` 文件。

DICOM 文件并非普通图像容器,其 Pixel Data(标签 (7FE0,0010))需严格遵循传输语法(Transfer Syntax)、光度解释(Photometric Interpretation)、位深(Bits Stored)等元数据约束。直接对 Dataset 对象切片(如 ds[500:1500, 500:1500])会失败——因为 pydicom 的 __getitem__ 仅支持按 DICOM 标签(Tag)索引,而非 NumPy 式数组切片。

真正的裁剪操作必须作用于 解码后的像素数组(ds.pixel_array),再将处理结果通过 ds.set_pixel_data() 安全写回,并显式维护关键图像属性。以下是经过验证、兼容单帧/多帧、支持常见压缩/非压缩格式(含 YBR_FULL_422)的稳健方案:

✅ 正确流程:加载 → 提取 → 裁剪 → 重置像素 → 保存

import pydicom
import numpy as np
import cv2

def crop_dicom_dcm(input_path: str, output_path: str, 
                   top: int, left: int, height: int, width: int):
    """
    裁剪 DICOM 文件中所有帧的指定矩形区域,并保存为新 DICOM 文件。

    Args:
        input_path: 原始 .dcm 文件路径
        output_path: 输出 .dcm 文件路径
        top, left: 裁剪起始坐标(y, x)
        height, width: 裁剪区域尺寸
    """
    ds = pydicom.dcmread(input_path)

    # 1. 获取像素数组 —— 自动处理单帧(2D)和多帧(3D/4D)情况
    pixel_array = ds.pixel_array
    if pixel_array.ndim == 2:
        # 单帧:扩展为 (1, H, W) 便于统一处理
        pixel_array = np.expand_dims(pixel_array, axis=0)
    elif pixel_array.ndim == 3 and pixel_array.shape[-1] in (3, 4):
        # RGB/RGBA 帧(如某些内窥镜或彩色超声),保持通道维度在最后
        pass
    else:
        # 多帧(如 CT/MRI 序列):形状为 (N, H, W)
        pass

    # 2. 执行逐帧裁剪(确保不越界)
    cropped_frames = []
    for i, frame in enumerate(pixel_array):
        h, w = frame.shape[:2]
        # 边界校验
        actual_top = max(0, min(top, h - 1))
        actual_left = max(0, min(left, w - 1))
        actual_h = max(1, min(height, h - actual_top))
        actual_w = max(1, min(width, w - actual_left))

        cropped = frame[actual_top:actual_top + actual_h,
                        actual_left:actual_left + actual_w]
        cropped_frames.append(cropped)

    # 3. 重建像素数组(保持原始维度结构)
    cropped_array = np.array(cropped_frames)
    if len(cropped_frames) == 1:
        cropped_array = cropped_array[0]  # 恢复为 2D(单帧)

    # 4. 关键:安全设置新像素数据 —— 自动适配 PhotometricInterpretation & BitsStored
    # 注意:set_pixel_data() 会自动更新 Rows/Columns/NumberOfFrames 等依赖字段
    ds.set_pixel_data(
        cropped_array,
        photometric_interpretation=ds.get("PhotometricInterpretation", "MONOCHROME2"),
        bits_stored=ds.get("BitsStored", 16),
        # 若原图含压缩(如 JPEG2000),需额外调用 encapsulate() —— 但本例假设非压缩
    )

    # 5. 【重要】清除可能冲突的旧像素相关私有标签(可选,增强兼容性)
    if hasattr(ds, 'PixelData'):
        del ds.PixelData

    # 6. 保存(pydicom 会自动选择合适传输语法)
    ds.save_as(output_path)
    print(f"✅ 裁剪完成:{output_path} | 形状 {cropped_array.shape}")

# 使用示例:裁剪从 (500, 500) 开始、1000×1000 像素的区域
crop_dicom_dcm(
    input_path=r"D:\praca\GUMED\dicom\mrxs\1_AORTA\AO_1_014_Masson\3_0.dcm",
    output_path=r"D:\praca\GUMED\dicom\mrxs\1_AORTA\AO_1_014_Masson\3_0-crop.dcm",
    top=500, left=500, height=1000, width=1000
)

⚠️ 关键注意事项

  • 避免 openslide 兼容性问题:YBR_FULL_422 报错源于裁剪后未重置 PhotometricInterpretation 或色彩空间不匹配。上述代码显式传递该值,并优先使用原始值;若目标软件(如 OpenSlide)仅支持 MONOCHROME2,可在 set_pixel_data() 中强制指定:

    ds.set_pixel_data(cropped_array, photometric_interpretation="MONOCHROME2", ...)

    并确保输入图像是灰度(必要时用 cv2.cvtColor(frame, cv2.COLOR_YCrCb2GRAY) 转换)。

  • 压缩格式处理:若原始 DICOM 使用 JPEG2000(1.2.840.10008.1.2.4.91)等压缩传输语法,set_pixel_data() 不会自动封装。此时需手动调用:

    librosa Python 音频与音乐分析库
    librosa Python 音频与音乐分析库

    librosa 是一个用于音频和音乐分析的 Python 库。它提供了特征提取、频谱分析、节拍跟踪、起始检测和音频可视化的工具,基于 NumPy 和 SciPy 构建,用于科学音频计算。

    下载
    from pydicom.encaps import encapsulate
    from pydicom.uid import JPEGBaseline
    # ... 裁剪后
    if ds.file_meta.TransferSyntaxUID.is_compressed:
        # 需先编码为 JPEG2000 字节流(需安装 openjpeg 或 pillow)
        # 此处简化为抛出提示 —— 生产环境建议转为无损压缩或显式解压
        raise RuntimeError("压缩 DICOM 裁剪需额外编码步骤,建议先转换为隐式 VR 小端序")
  • 元数据一致性:裁剪后 Rows/Columns 已由 set_pixel_data() 自动更新;但 ImagePositionPatient、PixelSpacing 等空间信息需根据实际物理坐标重新计算(若需精确配准),本例未修改以保持最小侵入。

✅ 验证输出

生成的 .dcm 文件可通过以下方式快速验证:

# 用 pydicom 读取并检查
ds_out = pydicom.dcmread(output_path)
print("Rows:", ds_out.Rows, "Columns:", ds_out.Columns)
print("Pixel Data shape:", ds_out.pixel_array.shape)
print("PhotometricInterpretation:", ds_out.PhotometricInterpretation)

# 用 ITK-SNAP 或 3D Slicer 直接打开确认可视化正常

此方法绕过了 cv2.imread() / PIL 等中间格式转换,全程在 DICOM 标准框架内操作,确保输出文件元数据完整、像素结构合规,完美满足多层 DICOM 数据统一分辨率预处理需求。

Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!

相关文章

PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

python

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
python打包成可执行文件
python打包成可执行文件

本专题为大家带来python打包成可执行文件相关的文章,大家可以免费的下载体验。

2023.07.20

1851

4

python能做什么
python能做什么

python能做的有:可用于开发基于控制台的应用程序、多媒体部分开发、用于开发基于Web的应用程序、使用python处理数据、系统编程等等。本专题为大家提供python相关的各种文章、以及下载和课程。

2023.07.25

5064

7

format在python中的用法
format在python中的用法

Python中的format是一种字符串格式化方法,用于将变量或值插入到字符串中的占位符位置。通过format方法,我们可以动态地构建字符串,使其包含不同值。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

2023.07.31

1809

3

python教程
python教程

Python已成为一门网红语言,即使是在非编程开发者当中,也掀起了一股学习的热潮。本专题为大家带来python教程的相关文章,大家可以免费体验学习。

2023.08.03

30497

23

python环境变量的配置
python环境变量的配置

Python是一种流行的编程语言,被广泛用于软件开发、数据分析和科学计算等领域。在安装Python之后,我们需要配置环境变量,以便在任何位置都能够访问Python的可执行文件。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

2023.08.04

3627

5

python eval
python eval

eval函数是Python中一个非常强大的函数,它可以将字符串作为Python代码进行执行,实现动态编程的效果。然而,由于其潜在的安全风险和性能问题,需要谨慎使用。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

2023.08.04

3627

5

scratch和python区别
scratch和python区别

scratch和python的区别:1、scratch是一种专为初学者设计的图形化编程语言,python是一种文本编程语言;2、scratch使用的是基于积木的编程语法,python采用更加传统的文本编程语法等等。本专题为大家提供scratch和python相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.11

1243

5

python合并两个列表
python合并两个列表

Python是一种强大的编程语言,具有许多方便的功能和工具。在Python中,有多种方法可以合并两个列表。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

2023.08.10

616

4

python是前端还是后端
python是前端还是后端

Python属于前端也属于后端,其灵活性和丰富的生态系统使得开发人员能够在不同的领域中灵活运用。本专题为大家提供python相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.11

2823

5

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程