penumonia / app.py
ABCREATIVEAKSHAY's picture
Upload 3 files
324d665 verified
Raw
History Blame Contribute Delete
3.63 kB
import os
import io
import numpy as np
from PIL import Image
import tensorflow as tf
from tensorflow import keras
from fastapi import FastAPI, UploadFile, File, HTTPException
from fastapi.middleware.cors import CORSMiddleware
# Initialize FastAPI app
app = FastAPI(
title="PneuVision AI API",
description="Backend API for MobileNetV2 Pneumonia Detection model",
version="1.0.0"
)
# Enable CORS so frontend deployed on Cloudflare can access this API
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
MODEL_PATH = "MobileNetV2_final.keras"
model = None
@app.on_event("startup")
def load_model():
global model
if os.path.exists(MODEL_PATH):
try:
# Load the Keras model. Keras 3 format handles both weights and architecture.
model = keras.models.load_model(MODEL_PATH)
print("[BACKEND] Model loaded successfully.")
except Exception as e:
print(f"[BACKEND] Error loading model: {e}")
else:
print(f"[BACKEND] Model file not found at {MODEL_PATH}")
@app.get("/")
def health_check():
"""Health check endpoint to see if API and model are active."""
return {
"status": "ready" if model is not None else "model_not_loaded",
"model_architecture": "MobileNetV2",
"input_shape": [224, 224, 3],
"classes": ["NORMAL", "PNEUMONIA"]
}
@app.post("/predict")
async def predict(file: UploadFile = File(...)):
"""Receives a chest X-ray image and predicts the probability of pneumonia."""
global model
if model is None:
raise HTTPException(
status_code=503,
detail="Model is not initialized on the server. Please check server logs."
)
if not file.content_type.startswith("image/"):
raise HTTPException(
status_code=400,
detail="Invalid file format. Please upload an image (JPEG/PNG)."
)
try:
# Read file contents and open image
contents = await file.read()
image = Image.open(io.BytesIO(contents)).convert("RGB")
# Preprocessing:
# 1. Resize image to 224x224 using Bilinear interpolation (matching Colab training setup)
image = image.resize((224, 224), Image.Resampling.BILINEAR)
img_array = np.array(image, dtype=np.float32)
# 2. Add batch dimension: shape (1, 224, 224, 3)
img_array = np.expand_dims(img_array, axis=0)
# Note: Rescaling (1.0/255.0) and Normalization (ImageNet mean/std)
# are defined inside the Keras model as layers, so we don't apply them here.
# Running model inference (returns shape [1, 2])
predictions = model.predict(img_array)
# Class 0: NORMAL, Class 1: PNEUMONIA
prob_normal = float(predictions[0][0])
prob_pneumonia = float(predictions[0][1])
predicted_class = "PNEUMONIA" if prob_pneumonia > prob_normal else "NORMAL"
confidence = max(prob_normal, prob_pneumonia)
return {
"prediction": predicted_class,
"confidence": confidence,
"probabilities": {
"NORMAL": prob_normal,
"PNEUMONIA": prob_pneumonia
},
"info": {
"model": "MobileNetV2",
"processed_shape": [224, 224, 3]
}
}
except Exception as e:
raise HTTPException(
status_code=500,
detail=f"Inference error: {str(e)}"
)