Spaces:
Build error
Build error
| import gradio as gr | |
| import torch | |
| import torch.nn.functional as F | |
| import nibabel as nib | |
| import numpy as np | |
| # Define the ConvAutoencoder model structure | |
| class ConvAutoencoder(torch.nn.Module): | |
| def __init__(self): | |
| super(ConvAutoencoder, self).__init__() | |
| # Encoder | |
| self.encoder = torch.nn.Sequential( | |
| torch.nn.Conv2d(1, 32, 3, stride=2, padding=1), | |
| torch.nn.ReLU(), | |
| torch.nn.Conv2d(32, 64, 3, stride=2, padding=1), | |
| torch.nn.ReLU() | |
| ) | |
| # Decoder | |
| self.decoder = torch.nn.Sequential( | |
| torch.nn.ConvTranspose2d(64, 32, 2, stride=2, padding=1), | |
| torch.nn.ReLU(), | |
| torch.nn.ConvTranspose2d(32, 1, 2, stride=2, padding=1), | |
| torch.nn.Sigmoid() | |
| ) | |
| def forward(self, x): | |
| x = self.encoder(x) | |
| x = self.decoder(x) | |
| return x | |
| # Load the pre-trained model | |
| model_path = "conv_autoencoder_model.pth" | |
| model = ConvAutoencoder() | |
| model.load_state_dict(torch.load(model_path, map_location=torch.device("cpu")), strict=False) | |
| model.eval() | |
| # Prediction function | |
| def predict(modalities): | |
| try: | |
| slices = [] | |
| for modality in modalities: | |
| nii_data = nib.load(modality).get_fdata() | |
| slices.append(nii_data) | |
| # Average modalities to create a single-channel image | |
| slice_avg = np.mean(slices, axis=0) | |
| # Select the slice with maximum non-zero pixels | |
| non_zero_counts = [np.count_nonzero(slice_avg.take(i, axis=2)) for i in range(slice_avg.shape[2])] | |
| max_index = np.argmax(non_zero_counts) | |
| best_slice = slice_avg.take(max_index, axis=2) | |
| # Convert best_slice to a tensor and resize to (256, 256) using interpolation | |
| tensor_slice = torch.tensor(best_slice).unsqueeze(0).unsqueeze(0).float() # Shape: [1, 1, H, W] | |
| # Force resize to (256, 256) | |
| tensor_slice_resized = F.interpolate(tensor_slice, size=(256, 256), mode="bilinear", align_corners=False) | |
| print(f"Tensor shape after forced resize: {tensor_slice_resized.shape}") # Debugging | |
| # Run model inference | |
| with torch.no_grad(): | |
| reconstruction = model(tensor_slice_resized) | |
| reconstruction_error = torch.abs(reconstruction - tensor_slice_resized).squeeze().numpy() | |
| # Anomaly detection | |
| error_threshold = 0.1 | |
| anomaly_detected = np.mean(reconstruction_error) > error_threshold | |
| anomaly_message = "Anomaly Detected" if anomaly_detected else "No Anomaly Detected" | |
| return reconstruction_error, anomaly_message | |
| except Exception as e: | |
| print(f"Processing error: {e}") | |
| return np.zeros((256, 256)), f"Processing error: {e}" | |
| # Gradio interface | |
| iface = gr.Interface( | |
| fn=predict, | |
| inputs=gr.Files(type="filepath", label="Upload NIfTI Modalities (e.g., T1, T2, FLAIR)"), | |
| outputs=[gr.Image(type="numpy", label="Reconstruction Error"), gr.Textbox(label="Anomaly Detection")], | |
| title="Brain MRI Anomaly Detection - ConvAutoencoder", | |
| description="Upload NIfTI files for brain anomaly detection using ConvAutoencoder.", | |
| ) | |
| iface.launch() | |