ValueError: The length of the pixel data in the dataset doesn’t match the expected length
问题:使用pydicom
读取dcm
数据时报错ValueError: The length of the pixel data in the dataset (248244 bytes) doesn't match the expected length (524288 bytes). The dataset may be corrupted or there may be an issue with the pixel data handler.
原使用代码如下:
import pydicom
path = "demo.dcm"
ds = pydicom.dcmread(path, force=True)
ds.file_meta.TransferSyntaxUID = pydicom.uid.ImplicitVRLittleEndian # or whatever is the correct transfer syntax for the file
data_array = ds.pixel_array # 此处报上述错误
原因:
经排查是ds.file_meta.TransferSyntaxUID = pydicom.uid.ImplicitVRLittleEndian
这行错误的问题, 以前使用pydicom
读取文件报错时,百度别人说加上这句就好, 确实当时解决了问题, 但后续没想到会导致别的问题, 这句意思是在dcm
文件缺少TransferSyntaxUID
这个属性的时候, 给赋默认值, 这个属性标识dcm
是否被压缩, 应该使用什么handler
去读取数据, 关于该属性的值对应的意思详见TransferSyntax, 那么使用如下代码判断文件是否被压缩
import pydicom
path = "demo.dcm"
ds = pydicom.dcmread(path, force=True)
TransferSyntaxUID = getattr(dicom.file_meta, 'TransferSyntaxUID', None) # 如果 TransferSyntaxUID 不是 None,
# 且 TransferSyntaxUID == '1.2.840.10008.1.2', 那么就是没压缩的数据, 如果 TransferSyntaxUID == '1.2.840.10008.1.2.4.70', 那么就代表数据是经过压缩的
修改后代码:
# 1. 安装 python-gdcm, 用于解析压缩dcm数据
pip install python-gdcm
# 2. 使用下述代码读取文件
import pydicom
path = "demo.dcm"
ds = pydicom.dcmread(path, force=True)
TransferSyntaxUID = getattr(dicom.file_meta, 'TransferSyntaxUID', None)
if TransferSyntaxUID: # 我遇到的数据中, 压缩后的dcm会有此标识, 未压缩过的数据没有此标识, 故如果此代码不适用你的场景, 还需再排查下别的问题
pass
else:
dicom.file_meta.TransferSyntaxUID = pydicom.uid.ImplicitVRLittleEndian
data_array = ds.pixel_array