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

应用LUT处理MRI DICOM后保存图像全黑的问题求助

DICOM LUT处理后保存全黑问题解决

核心原因

你生成的是8位像素数据(0-254),但未同步更新DICOM元数据中像素深度相关标签,导致阅读器仍按原始高比特深度(如16位)解析,8位数据在16位空间中数值极低,因此显示全黑。

关键修改点

  • 更新像素深度元数据:修改BitsAllocated、BitsStored、HighBit标签,告知阅读器当前是8位数据。
  • 修正代码变量错误:修复代码中变量名不一致的问题。
  • 优化LUT逻辑:处理所有像素值,避免遗漏或错误判断。

修改后的完整代码

import numpy as np
import pydicom

def make_lut(pixel_array, width, center, photometric_interp):
    """生成DICOM适用的LUT"""
    slope = 1.0
    intercept = 0.0
    min_px = int(np.amin(pixel_array))
    max_px = int(np.amax(pixel_array))
    lut = [0] * (max_px + 1)
    invert = photometric_interp == "MONOCHROME1"

    # 遍历所有原始像素值范围,包含max_px
    for px_value in range(min_px, max_px + 1):
        lut_value = px_value * slope + intercept
        # 窗宽窗心映射计算
        voi_value = ((lut_value - center) / width + 0.5) * 255.0
        clamped_value = np.clip(voi_value, 0, 255)
        lut[px_value] = round(255 - clamped_value) if invert else round(clamped_value)
    return lut

def apply_lut(pixels_in, lut):
    # 用numpy优化操作,处理所有像素
    pixels_flat = pixels_in.flatten()
    pixels_out = np.array([lut[px] if px < len(lut) else 0 for px in pixels_flat], dtype=np.uint8)
    return pixels_out.reshape(pixels_in.shape)

# 主处理流程
idx = 30
dcm_files = ["替换为你的DICOM文件路径列表"]
ds = pydicom.dcmread(dcm_files[idx])
raw_pixels = ds.pixel_array

# 获取窗宽窗心,无则用图像极值计算
if ds.WindowWidth and ds.WindowCenter:
    window_width = float(ds.WindowWidth)
    window_center = float(ds.WindowCenter)
else:
    window_width = np.amax(raw_pixels) - np.amin(raw_pixels)
    window_center = (np.amax(raw_pixels) + np.amin(raw_pixels)) / 2

# 生成并应用LUT
lut = make_lut(raw_pixels, window_width, window_center, ds.PhotometricInterpretation)
processed_pixels = apply_lut(raw_pixels, lut)

# 同步更新DICOM元数据
ds.PixelData = processed_pixels.tobytes()
# 设置8位像素相关标签
ds.BitsAllocated = 8
ds.BitsStored = 8
ds.HighBit = 7
# 指定无符号整数类型
ds.PixelRepresentation = 0

# 保存处理后的DICOM
ds.save_as("test_luted.dcm")

额外说明

  1. BitsAllocated:指每个像素分配的比特数,这里设为8;BitsStored指实际存储的有效比特数,同样设为8;HighBit是有效比特的最高位索引,8位数据为7(从0开始计数)。
  2. PixelRepresentation设为0表示无符号整数,符合0-255的8位灰度数据格式。
  3. 移除了apply_lut中if pixel > 0的判断,确保所有像素值都被LUT映射,避免暗部像素异常。

内容的提问来源于stack exchange,提问作者Behnam Yazdani

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 04:15:49