CoolFace
Apppublic

humantics/cxranalyzer

sourceHugging Faceapache-2.0updated 1y agoView on Hugging Face
0likes
app.py104 linesDownload Raw Back to root
1from fastapi import FastAPI,Query,HTTPException2import torchxrayvision as xrv3import skimage, torch, torchvision4import cv25import numpy as np6from pytorch_grad_cam import GradCAM7from pytorch_grad_cam.utils.model_targets import ClassifierOutputTarget8from transformers import pipeline9from PIL import Image10from fastapi.middleware.cors import CORSMiddleware11import requests12 13app = FastAPI()14# Add the frontend origin here15origins = [16    "http://localhost:8080",  # Your frontend running on port 808017    "http://127.0.0.1:8080"18]19 20app.add_middleware(21    CORSMiddleware,22    allow_origins=origins,  # OR ["*"] only during dev23    allow_credentials=True,24    allow_methods=["*"],25    allow_headers=["*"],26)27 28 29model = xrv.models.DenseNet(weights="densenet121-res224-all")30tb_classifier =pipeline("image-classification",model="vimal-humantics/dinov2-base-xray-224-finetuned-tb") 31 32 33 34 35def show_anomaly_bounding_box(img_tensor, model, class_index=None):36    target_layer = model.features[-1]37 38    cam = GradCAM(model=model, target_layers=[target_layer])39 40    with torch.no_grad():41        outputs = model(img_tensor[None, ...])42        pred_index = class_index if class_index is not None else torch.argmax(outputs[0]).item()43 44    grayscale_cam = cam(input_tensor=img_tensor[None, ...],45                        targets=[ClassifierOutputTarget(pred_index)])46    grayscale_cam = grayscale_cam[0, :]47 48    input_img = img_tensor.numpy()[0]49    input_img_norm = (input_img - input_img.min()) / (input_img.max() - input_img.min())50    input_img_rgb = cv2.cvtColor((input_img_norm * 255).astype(np.uint8), cv2.COLOR_GRAY2RGB)51 52    cam_resized = cv2.resize(grayscale_cam, (224, 224))53    cam_uint8 = (cam_resized * 255).astype(np.uint8)54    _, thresh = cv2.threshold(cam_uint8, 100, 255, cv2.THRESH_BINARY)55    contours, _ = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)56    bounding_box = ()57    for cnt in contours:58        x, y, w, h = cv2.boundingRect(cnt)59        bounding_box = ((x,y),(x+w,y+h))60        # cv2.rectangle(input_img_rgb, (x, y), (x + w, y + h), (0, 255, 0), 2)61 62    return bounding_box63 64@app.get("/")65def greet_json():66    return {"Hello": "World!"}67 68@app.get('/predict')69def predict(image_url:str = Query(..., description="URL to a chest X-ray image")):70    try:71        img = skimage.io.imread(image_url)72        img = xrv.datasets.normalize(img,255)73        img = img.mean(2)[None, ...]74        transform = torchvision.transforms.Compose([xrv.datasets.XRayCenterCrop(),xrv.datasets.XRayResizer(224)])75        img = transform(img)76        img = torch.from_numpy(img)77        outputs = model(img[None,...])78        79        prediction = dict(zip(model.pathologies,outputs[0].detach().numpy().tolist()))80        pred_class=outputs[0].argmax().item()81        pred_label = model.pathologies[pred_class]82        pred_output = {}83        for k,v in prediction.items():84            pred_output.update({k:round(v,2)})85 86        get_bounding_box = show_anomaly_bounding_box(img,model=model)87        # TB detection88        89        image = Image.open(requests.get(image_url, stream=True).raw)90        tb_finding = tb_classifier(images=image)91        tb_label = tb_finding[0]['label']92        print(tb_label)93        tb_score = round(tb_finding[0]['score'],2)94        tb_output = 095        if tb_label == "normal":96            tb_output = 1-tb_score97        else:98            tb_output = tb_score99 100        return {"prediction_result":pred_output,"bounding_box":{pred_label:get_bounding_box},"tb_finding":tb_output}101    except Exception as e:102        print(e)103        raise HTTPException(status_code=400, detail=f"Failed to fetch/process image: {str(e)}")104