Pydicom转Numpy处理后转回DICOM图像异常求助
Hi there! Let's break down why your processed DICOM is showing up green in viewers—this is a common issue with straightforward fixes once you know where to look.
1. You Forgot to Update PhotometricInterpretation
This is the #1 culprit for green-tinted images after switching to grayscale. When you set SamplesPerPixel = 1, you’re telling the DICOM this is single-channel data, but if you leave the original PhotometricInterpretation (e.g., "RGB" for color scans), viewers will still try to map the single channel to an RGB component. Since green is the second channel in RGB, your grayscale data gets incorrectly rendered as green by default.
Fix this by explicitly setting the photometric interpretation to a grayscale option:
# MONOCHROME2 is standard for medical images (white = high intensity) ds.PhotometricInterpretation = "MONOCHROME2" # Use MONOCHROME1 instead if you need black = high intensity # ds.PhotometricInterpretation = "MONOCHROME1"
2. Pixel Data Type & DICOM Tag Mismatch
DICOM viewers rely on tags like BitsAllocated, BitsStored, and HighBit to parse pixel values correctly. If your processed numpy array uses a different data type than what these tags specify, the viewer will misinterpret the data (leading to color or intensity glitches).
For example, if the original DICOM uses 16-bit unsigned integers, ensure your processed array matches that type before converting to bytes:
# Match the data type to the original DICOM's pixel array processed_mat = processed_mat.astype(ds.pixel_array.dtype) # If you intentionally changed the bit depth, update the tags too: # ds.BitsAllocated = 8 # ds.BitsStored = 8 # ds.HighBit = 7 # processed_mat = processed_mat.astype(np.uint8)
3. Unnecessary Reshaping of Pixel Data
DICOM’s PixelData expects a flat, continuous byte stream—you don’t need to reshape into multi-dimensional arrays before converting to bytes. Your current reshape to (p, f, r, c) is redundant and could introduce ordering errors. Instead, flatten your processed array directly:
# Flatten the processed array (frames × rows × columns × samples) to 1D ds.PixelData = processed_mat.flatten(order='C').tobytes()
This ensures pixel data is stored in the order viewers expect: all rows of a frame, followed by all frames, with single-channel samples packed sequentially.
4. Byte Order (Endianness) Mismatch
DICOM uses either Little Endian or Big Endian byte ordering, specified in TransferSyntaxUID. If your numpy array’s byte order doesn’t match this, the viewer will read pixel values incorrectly.
Fix this by aligning the array’s byte order with the DICOM’s transfer syntax:
# Match the byte order to the DICOM's setting if ds.is_little_endian: processed_mat = processed_mat.astype(f'<{ds.pixel_array.dtype.str[1:]}') else: processed_mat = processed_mat.astype(f'>{ds.pixel_array.dtype.str[1:]}')
Quick Test to Confirm
Start with updating PhotometricInterpretation first—this will fix the green tint in most cases. If that doesn’t work, verify the data type and byte order match the DICOM tags.
内容的提问来源于stack exchange,提问作者ahdrules

