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

如何快速读取大型DICOM文件像素数组首帧为numpy数组

问题:大型多帧DICOM快速读取首帧为numpy数组

问题描述

现有一大型DICOM文件,需要尽可能快速地将其像素数组的第一帧读取为numpy数组格式。
初始读取代码如下:

import pydicom

directory = # 目标DICOM文件存储路径
dicom = pydicom.dcmread(directory)

参考通用方案读取首帧的代码为:

first_image = dicom.pixel_array[0]

当前手头的DICOM文件像素数组形状为(1691, 555, 800, 3),执行dicom.pixel_array全量读取耗时约12秒。由于需要批量处理大量同类DICOM文件的首帧读取任务,需要效率更高的实现方案。

已尝试的思路

曾尝试直接读取像素数据字节段dicom[0x7fe0,0x0010]._value,计划提取首帧对应字节段后转换为numpy数组,但无法确定首帧在字节段中的准确范围。
参考公开技术资料给出的像素数据长度计算公式:
ROWS * COLUMNS * NUMBER_OF_FRAMES * SAMPLES_PER_PIXEL * (BITS_ALLOCATED/8)
在当前场景下计算结果为1332000,该值无法整除实际像素数据长度122320858,无法参考该公式定位首帧字节位置。


解答

长度不匹配的核心原因是:你使用的DICOM文件采用了压缩传输语法(常见如JPEG基线、JPEG2000、RLE无损压缩等),标签(0x7FE0, 0x0010)中存储的不是连续排列的裸像素字节,而是符合DICOM封装格式的压缩帧集合,包含帧偏移表、帧分隔符等额外结构字节,因此裸像素长度公式计算结果必然和实际存储长度不匹配。

不需要手动计算字节偏移,pydicom 2.0及以上版本已经提供了单帧解码的原生优化接口,不会解码所有帧,速度可以提升两个数量级以上:

方案1:最简实现(推荐90%场景使用)

直接调用内置的单帧解码接口,仅解码目标帧,跳过其余1690帧的解码流程:

from pydicom import dcmread
from pydicom.pixels import decode_frame

# 读取文件元数据,默认不会触发全量像素解码
ds = dcmread("your_dicom_file.dcm")
# 仅解码第0帧(即第一帧),返回格式为标准numpy数组
first_frame = decode_frame(ds, frame_number=0)

该方案常规耗时在几十毫秒级别,相比全量读取12秒的耗时提升非常明显,且自动处理传输语法适配、像素位深转换、颜色空间修正等逻辑,返回的numpy数组和全量读取ds.pixel_array[0]的结果完全一致,不需要额外做格式兼容处理。

方案2:极致性能优化(适合超大规模批量处理场景)

如果需要进一步压缩耗时,可以直接提取第一帧的压缩字节段,跳过其他帧的字节读取和解码流程:

from pydicom import dcmread
from pydicom.encaps import get_frame_offsets
from pydicom.pixels import decode_frame

# 可选开启lazy模式,仅加载必要元数据,不读入全量文件内容
ds = dcmread("your_dicom_file.dcm", lazy=True)
# 获取所有压缩帧在PixelData中的字节偏移位置
frame_offsets, _ = get_frame_offsets(ds.PixelData)
# 切片提取第一帧对应的压缩字节段
first_frame_bytes = ds.PixelData[frame_offsets[0]:frame_offsets[1]]
# 仅解码第一帧的压缩数据
first_frame = decode_frame(
    ds,
    compressed_data=first_frame_bytes,
    frame_number=0
)

该方案可以进一步减少内存占用和IO耗时,适合单文件大小超过1GB、批量处理文件量过万的场景。

注意事项

  • 不要直接访问ds.pixel_array属性,该属性会触发所有帧的全量解码,是之前读取耗时过长的核心原因
  • 裸像素长度计算公式仅适用于非压缩传输语法(Implicit VR Little Endian、Explicit VR Little Endian、Explicit VR Big Endian三类),所有带压缩的传输语法都不能用这个公式计算帧偏移
  • 如果使用的pydicom版本低于2.0,请先升级到最新稳定版,旧版本没有提供单帧解码的优化接口

内容的提问来源于stack exchange,提问作者温泽海

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 04:21:13