|
import gradio as gr |
|
import os |
|
from typing import Tuple, Optional |
|
import os |
|
import shutil |
|
import sys |
|
from pathlib import Path |
|
import cv2 |
|
import gradio as gr |
|
import numpy as np |
|
import spaces |
|
|
|
import torch |
|
from PIL import Image |
|
from tqdm import tqdm |
|
import sys |
|
from pathlib import Path |
|
from huggingface_hub import login |
|
|
|
|
|
|
|
token = os.getenv("HF_TOKEN") |
|
if token: |
|
login(token=token) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
current_dir = Path(__file__).parent |
|
sys.path.append(str(current_dir)) |
|
|
|
|
|
|
|
|
|
from modeling.BaseModel import BaseModel |
|
from modeling import build_model |
|
from utilities.arguments import load_opt_from_config_files |
|
from utilities.constants import BIOMED_CLASSES |
|
from inference_utils.inference import interactive_infer_image |
|
from inference_utils.output_processing import check_mask_stats |
|
from inference_utils.processing_utils import read_rgb |
|
|
|
import spaces |
|
|
|
|
|
MARKDOWN = """ |
|
<div align="center"> |
|
|
|
# HakimAI |
|
|
|
<h1 style="font-size: 2.5em; margin-bottom: 10px;"> |
|
ሀ<span style="color: #32CD32;">A</span>ኪ<span style="color: #FFD700;">i</span>ም |
|
<sup style="font-size: 0.5em;">AI</sup> |
|
</h1> |
|
|
|
<div style="margin: 20px 0;"> |
|
<a href="https://cyberbrainai.com/" style="margin: 0 5px;"> |
|
<img src="https://cyberbrainai.com/assets/logo.svg" alt="CyberBrain AI" style="width:50px; height:50px;"> |
|
</a> |
|
<a href="https://colab.research.google.com/github/roboflow-ai/notebooks/blob/main/notebooks/how-to-segment-images-with-sam-2.ipynb" style="margin: 0 5px;"> |
|
<img src="https://colab.research.google.com/assets/colab-badge.svg" alt="ድinቅneሽ"> |
|
</a> |
|
<a href="https://www.youtube.com/watch?v=Dv003fTyO-Y" style="margin: 0 5px;"> |
|
<img src="https://badges.aleen42.com/src/youtube.svg" alt="YouTube"> |
|
</a> |
|
</div> |
|
|
|
<div style="max-width: 800px; margin: 0 auto; text-align: left;"> |
|
|
|
This demo integrates BiomedParse, a foundation model for joint segmentation, detection, and recognition across 9 biomedical imaging modalities. The model supports: |
|
|
|
- Segmentation/Detection/Recognition across multiple modalities (CT, MRI, X-Ray, etc.) |
|
- Text-prompted object detection |
|
- Recognition of anatomical structures and abnormalities |
|
|
|
</div> |
|
|
|
</div> |
|
""" |
|
|
|
IMAGE_PROCESSING_EXAMPLES = [ |
|
["BiomedParse Segmentation", |
|
"https://raw.githubusercontent.com/microsoft/BiomedParse/main/examples/T0011.jpg", |
|
"Optic disc in retinal Fundus"], |
|
["BiomedParse Segmentation", |
|
"https://raw.githubusercontent.com/microsoft/BiomedParse/main/examples/Part_3_226_pathology_breast.png", |
|
"optic disc, optic cup"], |
|
["BiomedParse Segmentation", |
|
"https://raw.githubusercontent.com/microsoft/BiomedParse/main/examples/covid_1585.png", |
|
"COVID-19 infection in chest X-Ray"], |
|
["BiomedParse Segmentation", |
|
"https://raw.githubusercontent.com/microsoft/BiomedParse/main/examples/TCGA_HT_7856_19950831_8_MRI-FLAIR_brain.png", |
|
"Lower-grade glioma in brain MRI"], |
|
["BiomedParse Segmentation", |
|
"https://raw.githubusercontent.com/microsoft/BiomedParse/main/examples/LIDC-IDRI-0140_143_280_CT_lung.png", |
|
"COVID-19 infection in chest CT"], |
|
["BiomedParse Segmentation", |
|
"https://raw.githubusercontent.com/microsoft/BiomedParse/main/examples/144DME_as_F.jpeg", |
|
"Cystoid macular edema in retinal OCT"], |
|
["BiomedParse Segmentation", |
|
"https://raw.githubusercontent.com/microsoft/BiomedParse/main/examples/Part_1_516_pathology_breast.png", |
|
"Glandular structure in colon Pathology"], |
|
["BiomedParse Segmentation", |
|
"https://raw.githubusercontent.com/microsoft/BiomedParse/main/examples/ISIC_0015551.jpg", |
|
"Melanoma in skin Dermoscopy"], |
|
["BiomedParse Segmentation", |
|
"https://raw.githubusercontent.com/microsoft/BiomedParse/main/examples/C3_EndoCV2021_00462.jpg", |
|
"Neoplastic polyp in colon Endoscope"] |
|
] |
|
|
|
BIOMEDPARSE_MODES = { |
|
"CT": ["abdomen", "colon", "liver", "lung", "pelvis"], |
|
"MRI": ["brain", "heart", "prostate", "abdomen"], |
|
"MRI-FLAIR": ["brain"], |
|
"MRI-T1-Gd": ["brain"], |
|
"MRI-T2": ["prostate"], |
|
"OCT": ["retinal"], |
|
"X-Ray": ["chest"], |
|
"Dermoscopy": ["skin"], |
|
"Endoscope": ["colon"], |
|
"Fundus": ["retinal"], |
|
"Pathology": ["bladder", "breast", "cervix", "colon", "esophagus", "kidney", |
|
"liver", "ovarian", "prostate", "stomach", "testis", "thyroid", "uterus"], |
|
"Ultrasound": ["breast", "heart", "transperineal"] |
|
} |
|
|
|
IMAGE_INFERENCE_MODES = [ |
|
"BIOMED SEGMENTATION", |
|
"BIOMED DETECTION", |
|
"BIOMED RECOGNITION", |
|
"BIOMED SEGMENTATION + DETECTION", |
|
"BIOMED SEGMENTATION + RECOGNITION", |
|
"BIOMED DETECTION + RECOGNITION", |
|
"BIOMED SEGMENTATION + DETECTION + RECOGNITION" |
|
] |
|
|
|
|
|
def on_mode_dropdown_change(selected_mode): |
|
if selected_mode in IMAGE_INFERENCE_MODES: |
|
|
|
return [ |
|
gr.Dropdown(visible=True, choices=list(BIOMEDPARSE_MODES.keys()), label="Modality"), |
|
gr.Dropdown(visible=True, label="Anatomical Site"), |
|
gr.Textbox(visible=False), |
|
gr.Textbox(visible=False) |
|
] |
|
else: |
|
|
|
return [ |
|
gr.Dropdown(visible=False), |
|
gr.Dropdown(visible=False), |
|
gr.Textbox(visible=True), |
|
gr.Textbox(visible=(selected_mode == None)) |
|
] |
|
|
|
def on_modality_change(modality): |
|
if modality: |
|
return gr.Dropdown(choices=BIOMEDPARSE_MODES[modality], visible=True) |
|
return gr.Dropdown(visible=False) |
|
|
|
|
|
def initialize_model(): |
|
opt = load_opt_from_config_files(["configs/biomedparse_inference.yaml"]) |
|
pretrained_pth = 'hf_hub:microsoft/BiomedParse' |
|
opt['device'] = 'cuda' if torch.cuda.is_available() else 'cpu' |
|
model = BaseModel(opt, build_model(opt)).from_pretrained(pretrained_pth).eval() |
|
with torch.no_grad(): |
|
model.model.sem_seg_head.predictor.lang_encoder.get_text_embeddings( |
|
BIOMED_CLASSES + ["background"], is_eval=True |
|
) |
|
return model |
|
|
|
|
|
model = initialize_model() |
|
|
|
|
|
|
|
@spaces.GPU |
|
@torch.inference_mode() |
|
@torch.autocast(device_type="cuda", dtype=torch.bfloat16) |
|
def process_image(image_path, text_prompts, modality): |
|
image = read_rgb(image_path) |
|
text_prompts = [prompt.strip() for prompt in text_prompts.split(',')] |
|
|
|
|
|
pred_masks = interactive_infer_image(model, Image.fromarray(image), text_prompts) |
|
|
|
|
|
results = [] |
|
dice_scores = [] |
|
p_values = [] |
|
|
|
for i, prompt in enumerate(text_prompts): |
|
|
|
print("PROMPT: ", prompt, flush=True) |
|
p_value = check_mask_stats(image, pred_masks[i] * 255, modality, prompt) |
|
p_values.append(f"P-value for '{prompt}' ({modality}): {p_value:.4f}") |
|
|
|
|
|
overlay_image = image.copy() |
|
overlay_image[pred_masks[i] > 0.5] = [255, 0, 0] |
|
results.append(overlay_image) |
|
|
|
return results, p_values |
|
|
|
|
|
with gr.Blocks() as demo: |
|
gr.Markdown(MARKDOWN) |
|
with gr.Row(): |
|
with gr.Column(): |
|
image_input = gr.Image(type="filepath", label="Input Image") |
|
prompts_input = gr.Textbox(lines=2, placeholder="Enter prompts separated by commas...", label="Prompts") |
|
modality_dropdown = gr.Dropdown( |
|
choices=list(BIOMEDPARSE_MODES.keys()), |
|
value=list(BIOMEDPARSE_MODES.keys())[0], |
|
label="Modality" |
|
) |
|
submit_btn = gr.Button("Submit") |
|
with gr.Column(): |
|
output_gallery = gr.Gallery(label="Predicted Masks") |
|
pvalue_output = gr.Textbox(label="P-values", interactive=False) |
|
|
|
submit_btn.click( |
|
process_image, |
|
inputs=[image_input, prompts_input, modality_dropdown], |
|
outputs=[output_gallery, pvalue_output] |
|
) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
demo.launch() |