File size: 1,762 Bytes
b412062
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
import pydicom
import numpy as np
import logging
from PIL import Image

logger = logging.getLogger(__name__)

def read_dicom_image(file_path):
    """
    Reads a DICOM file and returns it as a NumPy array (grayscale).
    Handles pixel value scaling and content storage mechanism.
    """
    try:
        ds = pydicom.dcmread(file_path)
        
        # Handle pixel data
        if 'PixelData' not in ds:
            raise ValueError(f"No pixel data found in {file_path}")

        image_data = ds.pixel_array.astype(float)

        # Handle RescaleSlope and RescaleIntercept if present (Map to Hounsfield Units or physical values)
        slope = getattr(ds, 'RescaleSlope', 1.0)
        intercept = getattr(ds, 'RescaleIntercept', 0.0)
        image_data = image_data * slope + intercept

        # Normalize to 0-255 range for consistency with standard image processing
        # Note: This discards absolute physical values but preserves structure for the model
        image_min = np.min(image_data)
        image_max = np.max(image_data)
        
        if image_max != image_min:
            image_data = (image_data - image_min) / (image_max - image_min) * 255.0
        else:
            image_data = np.zeros_like(image_data)
        
        image_data = image_data.astype(np.uint8)

        # Handle photometric interpretation (invert if needed)
        # MONOCHROME1 typically means 0 is white, 255 is black (inverse of standard X-ray)
        # We generally want air (black) to be low, bone (white) to be high
        if ds.PhotometricInterpretation == "MONOCHROME1":
             image_data = 255 - image_data

        return image_data

    except Exception as e:
        logger.error(f"Error reading DICOM {file_path}: {e}")
        raise