| import base64 |
| import io |
|
|
| import numpy as np |
| from PIL import Image |
| import torch |
| import torchxrayvision as xrv |
|
|
| def init(): |
| """ |
| Called once at container startup. |
| Loads the DenseNet model from torchxrayvision (using HF Hub weights) |
| and sets up the crop transform. |
| """ |
| global model, transform |
| model_name = "densenet121-res224-chex" |
| model = xrv.models.get_model(model_name, from_hf_hub=True) |
| model.eval() |
| |
| transform = xrv.datasets.XRayCenterCrop(pad=32) |
|
|
| def predict(request): |
| """ |
| Called on each inference request. |
| Expects a JSON payload like {"image": "data:image/jpeg;base64,/9j/4AAQ..."}. |
| Returns a dict with scores and labels. |
| """ |
| |
| data_uri = request.json.get("image", "") |
| b64 = data_uri.split(",")[-1] |
| img = Image.open(io.BytesIO(base64.b64decode(b64))).convert("RGB") |
|
|
| |
| arr = np.array(img) |
| arr = xrv.datasets.normalize(arr, 255) |
|
|
| |
| arr = transform(arr) |
| tensor = torch.tensor(arr).permute(2, 0, 1).float().unsqueeze(0) |
|
|
| |
| with torch.no_grad(): |
| scores = model(tensor).tolist() |
|
|
| |
| return {"scores": scores, "labels": model.pathologies} |
|
|