def preprocess_xray(image_path, target_size=(224, 224), train_mean=0.482, train_std=0.236): """ Full preprocessing pipeline for chest X-ray images. Applies all six pillars in order. """ # Pillar 4: Validate first — skip corrupted files if not is_valid_image(image_path): return None image = cv2.imread(image_path, cv2.IMREAD_GRAYSCALE) # Pillar 5: Resize with aspect ratio preserved image = resize_with_padding(image, target_size) # Pillar 6: Gentle denoising image = cv2.medianBlur(image, 3) # Pillar 3: Enhance contrast to highlight lung texture clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8, 8)) image = clahe.apply(image) # Pillar 1: Scale to [0, 1] image = image.astype(np.float32) / 255.0 # Pillar 2: Normalize using training set statistics image = (image - train_mean) / train_std return image