Spaces:
Sleeping
Sleeping
| 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 | |