调整DICOM图像时Pydicom报ValueError:像素数据长度不匹配
DICOM像素长度不匹配错误解决方法
这个错误的核心是修改像素数据尺寸后没同步更新DICOM元数据。DICOM读取时会根据Rows、Columns、BitsAllocated这些元数据计算预期的像素字节数,实际存储的PixelData字节数和计算值对不上就会触发报错。比如你原图像是512×768、16位(每像素2字节),预期字节数是512×768×2=786432;调整成512×512后,要是元数据还是旧尺寸,或者位深没同步改,就会出现预期和实际长度不符的情况。
核心修正点
- 调整图像后,必须把DICOM数据集的
Rows和Columns改成新的512×512 - 如果调整时改了像素位深(比如从16位转8位),要同步更新
BitsAllocated、BitsStored、HighBit字段 - 确保最终
PixelData字节数 =Rows × Columns × (BitsAllocated ÷ 8)
修正后的示例代码
import pydicom import numpy as np from PIL import Image # 读原始DICOM ds = pydicom.dcmread("input.dcm") # 转成PIL图像(这里假设原始是16位无符号数据,根据实际情况调整) pixel_array = ds.pixel_array img = Image.fromarray(pixel_array) # 按比例缩放到长边512 width, height = img.size scale = 512 / max(width, height) new_size = (int(width * scale), int(height * scale)) resized_img = img.resize(new_size, Image.Resampling.LANCZOS) # 创建512×512画布补零 final_img = Image.new(img.mode, (512, 512), 0) paste_pos = ((512 - new_size[0])//2, (512 - new_size[1])//2) final_img.paste(resized_img, paste_pos) # 转回numpy数组 final_array = np.array(final_img) # -------------------------- 关键:更新元数据 -------------------------- ds.Rows = 512 ds.Columns = 512 # 要是改了位深(比如从uint16转uint8),要加下面这几行: # ds.BitsAllocated = 8 # ds.BitsStored = 8 # ds.HighBit = 7 # 写入处理后的像素数据 ds.PixelData = final_array.tobytes() # 保存文件 ds.save_as("output.dcm") # 验证读取 test_ds = pydicom.dcmread("output.dcm") print(test_ds.pixel_array.shape) # 输出 (512, 512) 就说明成功了
排查注意事项
- 检查原始DICOM的
PhotometricInterpretation字段(比如MONOCHROME1/MONOCHROME2),调整图像时别搞反灰度,不然显示会异常 - 如果原始数据有
WindowCenter、WindowWidth,可以根据新图像的灰度范围调整,或者保留原字段(不影响读取,但可能影响显示效果) - 尽量保持
final_array的 dtype 和原始pixel_array一致,除非你特意要改位深,那一定要同步更新元数据里的位深字段
内容的提问来源于stack exchange,提问作者Abhimanyu Anand
相关产品推荐
相关产品推荐

