medicalmodel / app.py
walaa2022's picture
Update app.py
deed5ef verified
raw
history blame
18.3 kB
#!/usr/bin/env python3
"""
Gemini Vision Pro Medical Image Analysis - Gradio Interface
Lightweight alternative using Google's Gemini Vision Pro API
"""
import gradio as gr
import google.generativeai as genai
from PIL import Image
import json
import time
import os
from typing import Dict, List, Optional, Tuple
import base64
import io
import warnings
warnings.filterwarnings("ignore")
# Global configuration
GEMINI_MODEL = None
API_KEY = None
def setup_gemini(api_key: str = None):
"""Setup Gemini Vision Pro with API key"""
global GEMINI_MODEL, API_KEY
# Try to get API key from environment or parameter
if api_key:
API_KEY = api_key
else:
API_KEY = os.getenv('GOOGLE_API_KEY') or os.getenv('GEMINI_API_KEY')
if not API_KEY:
return False, "❌ No API key provided. Please set GOOGLE_API_KEY environment variable or enter it in the interface."
try:
# Configure the API
genai.configure(api_key=API_KEY)
# Initialize the model
GEMINI_MODEL = genai.GenerativeModel('gemini-1.5-pro')
# Test the connection
test_response = GEMINI_MODEL.generate_content("Hello, can you help with medical image analysis?")
if test_response and test_response.text:
return True, "βœ… Gemini Vision Pro connected successfully!"
else:
return False, "❌ Failed to connect to Gemini API"
except Exception as e:
return False, f"❌ Gemini setup failed: {str(e)}"
def create_medical_prompt(clinical_data: Dict, analysis_type: str, focus_areas: str) -> str:
"""Create optimized medical analysis prompt for Gemini"""
base_prompt = """You are an expert medical AI assistant specializing in medical image analysis. You have extensive training across radiology, pathology, dermatology, ophthalmology, and clinical medicine.
**ANALYSIS INSTRUCTIONS:**
Analyze this medical image systematically and professionally:
- Use clear medical terminology with explanations for complex terms
- Structure your response with clear sections and headers
- Be thorough but concise
- Always mention limitations and emphasize the need for professional medical consultation
- Focus on observable findings rather than definitive diagnoses
"""
# Add clinical context if provided
clinical_context = ""
if clinical_data and any(v.strip() for v in clinical_data.values() if v):
clinical_context = "\n**CLINICAL CONTEXT:**\n"
context_items = []
if clinical_data.get("age"): context_items.append(f"Patient Age: {clinical_data['age']}")
if clinical_data.get("gender"): context_items.append(f"Gender: {clinical_data['gender']}")
if clinical_data.get("symptoms"): context_items.append(f"Presenting Symptoms: {clinical_data['symptoms']}")
if clinical_data.get("history"): context_items.append(f"Medical History: {clinical_data['history']}")
if clinical_data.get("medications"): context_items.append(f"Current Medications: {clinical_data['medications']}")
clinical_context += "\n".join(f"β€’ {item}" for item in context_items) + "\n"
# Analysis type specific instructions
analysis_instructions = {
"Comprehensive": """
**PROVIDE COMPREHENSIVE ANALYSIS WITH THESE SECTIONS:**
## 1. IMAGE ASSESSMENT
- Image type, quality, and technical adequacy
- Anatomical structures and regions visible
- Any artifacts or limitations
## 2. CLINICAL FINDINGS
- Normal anatomical structures observed
- Abnormal findings or variations from normal
- Specific measurements or quantitative observations if applicable
## 3. CLINICAL INTERPRETATION
- Significance of the findings
- Differential diagnostic considerations
- Correlation with provided clinical history
## 4. RECOMMENDATIONS
- Suggested next steps or additional imaging
- Clinical correlation recommendations
- Follow-up suggestions
## 5. LIMITATIONS & DISCLAIMERS
- What cannot be determined from this image alone
- Need for clinical correlation and professional evaluation
""",
"Quick Assessment": """
**PROVIDE FOCUSED QUICK ASSESSMENT:**
## KEY FINDINGS
- Most significant observations
- Normal vs abnormal structures
## CLINICAL IMPRESSION
- Primary considerations based on image
- Any urgent findings that require immediate attention
## IMMEDIATE RECOMMENDATIONS
- Essential next steps
- Urgency level assessment
## LIMITATIONS
- Important caveats about this assessment
""",
"Educational": """
**PROVIDE EDUCATIONAL ANALYSIS:**
## LEARNING OBJECTIVES
- Key educational points from this case
- Important anatomical or pathological concepts
## NORMAL vs ABNORMAL
- Clear explanation of what's normal in this image
- Detailed description of any abnormal findings
## CLINICAL CORRELATION
- How image findings relate to symptoms/history
- Real-world clinical significance
## TEACHING PEARLS
- Important concepts this case demonstrates
- Common pitfalls or considerations
"""
}
focus_instruction = ""
if focus_areas and focus_areas.strip():
focus_instruction = f"\n**SPECIAL FOCUS AREAS**: Pay particular attention to: {focus_areas}\n"
disclaimer = """
**IMPORTANT MEDICAL DISCLAIMER**:
This AI-powered analysis is for educational and research purposes only. It should never replace professional medical diagnosis, treatment, or consultation with qualified healthcare providers. Always seek professional medical advice for any health concerns or medical decisions.
"""
return base_prompt + clinical_context + analysis_instructions.get(analysis_type, analysis_instructions["Comprehensive"]) + focus_instruction + disclaimer
def analyze_medical_image_gemini(
image: Image.Image,
age: str,
gender: str,
symptoms: str,
history: str,
medications: str,
analysis_type: str,
focus_areas: str,
api_key: str,
progress=gr.Progress()
) -> Tuple[str, str, str]:
"""Main analysis function using Gemini Vision Pro"""
if image is None:
return "❌ Please upload an image first.", "", "❌ No image provided"
# Setup Gemini if needed
progress(0.1, desc="Connecting to Gemini...")
success, status = setup_gemini(api_key)
if not success:
return status, "", status
try:
progress(0.3, desc="Preparing analysis...")
# Prepare clinical data
clinical_data = {
"age": age.strip(),
"gender": gender,
"symptoms": symptoms.strip(),
"history": history.strip(),
"medications": medications.strip()
}
# Create prompt
prompt = create_medical_prompt(clinical_data, analysis_type, focus_areas)
progress(0.5, desc="Analyzing image with Gemini...")
# Generate analysis using Gemini Vision Pro
response = GEMINI_MODEL.generate_content([prompt, image])
if not response or not response.text:
return "❌ No response received from Gemini API", "", "❌ Analysis failed"
progress(0.9, desc="Preparing results...")
# Create download content
report_data = {
"timestamp": time.strftime("%Y-%m-%d %H:%M:%S UTC"),
"model": "Google Gemini-1.5-Pro Vision",
"analysis_type": analysis_type,
"clinical_data": clinical_data,
"focus_areas": focus_areas,
"analysis": response.text
}
download_content = json.dumps(report_data, indent=2)
progress(1.0, desc="Analysis complete!")
return response.text, download_content, "βœ… Analysis completed successfully"
except Exception as e:
error_msg = f"❌ Analysis failed: {str(e)}"
if "API_KEY" in str(e):
error_msg += "\n\nπŸ’‘ Tip: Make sure your Google API key is valid and has access to Gemini API"
elif "quota" in str(e).lower():
error_msg += "\n\nπŸ’‘ Tip: You may have exceeded your API quota. Check your Google Cloud Console"
elif "safety" in str(e).lower():
error_msg += "\n\nπŸ’‘ Tip: The image may have been blocked by safety filters. Try a different medical image"
return error_msg, "", error_msg
def create_interface():
"""Create the Gradio interface for Gemini Vision Pro"""
# Custom CSS for medical theme
css = """
.gradio-container {
max-width: 1400px !important;
}
.medical-header {
text-align: center;
color: #1a73e8;
margin-bottom: 20px;
}
.api-section {
background-color: #e8f0fe;
padding: 15px;
border-radius: 8px;
margin: 10px 0;
border-left: 4px solid #1a73e8;
}
.status-success {
color: #137333;
font-weight: 500;
}
.status-error {
color: #d93025;
font-weight: 500;
}
"""
with gr.Blocks(css=css, theme=gr.themes.Soft(), title="Gemini Medical AI") as interface:
# Header
gr.HTML("""
<div class="medical-header">
<h1>πŸ₯ Medical Image AI Analyzer</h1>
<h2>πŸ€– Powered by Google Gemini Vision Pro</h2>
<p><em>Fast, efficient medical image analysis using Google's latest AI</em></p>
</div>
""")
# API Configuration Section
with gr.Accordion("πŸ”‘ API Configuration", open=True):
gr.Markdown("""
### Google Gemini API Setup
You need a Google API key to use Gemini Vision Pro. Get one from [Google AI Studio](https://makersuite.google.com/app/apikey).
""")
api_key_input = gr.Textbox(
label="Google API Key",
type="password",
placeholder="Enter your Google API key here...",
info="Your API key is not stored and only used for this session"
)
status_display = gr.Textbox(
label="Connection Status",
value="⏳ Enter API key to connect",
interactive=False
)
with gr.Row():
# Left column - Inputs
with gr.Column(scale=1):
gr.Markdown("## πŸ“€ Upload Medical Image")
image_input = gr.Image(
type="pil",
label="Medical Image",
height=300,
sources=["upload", "clipboard", "webcam"]
)
gr.Markdown("*Supported: X-rays, CT, MRI, photographs, microscopy, dermatology images, etc.*")
gr.Markdown("## πŸ“‹ Clinical Information")
with gr.Group():
with gr.Row():
age_input = gr.Textbox(
label="Patient Age",
placeholder="e.g., 45 years",
max_lines=1
)
gender_input = gr.Dropdown(
choices=["", "Male", "Female", "Other"],
label="Gender",
value=""
)
symptoms_input = gr.Textbox(
label="Chief Complaint / Symptoms",
placeholder="e.g., Chest pain, shortness of breath for 3 days",
lines=2
)
history_input = gr.Textbox(
label="Medical History",
placeholder="e.g., Hypertension, diabetes, previous surgeries",
lines=2
)
medications_input = gr.Textbox(
label="Current Medications",
placeholder="e.g., Metformin, Lisinopril, Aspirin",
lines=2
)
gr.Markdown("## βš™οΈ Analysis Settings")
analysis_type = gr.Radio(
choices=["Comprehensive", "Quick Assessment", "Educational"],
label="Analysis Type",
value="Comprehensive",
info="Choose the depth and focus of analysis"
)
focus_areas = gr.Textbox(
label="Focus Areas (Optional)",
placeholder="e.g., cardiac silhouette, lung fields, bone density",
info="Specific areas to emphasize in analysis"
)
analyze_btn = gr.Button(
"πŸ”¬ Analyze with Gemini",
variant="primary",
size="lg"
)
# Right column - Results
with gr.Column(scale=1):
gr.Markdown("## πŸ€– AI Analysis Results")
analysis_output = gr.Textbox(
label="Medical Analysis",
lines=25,
max_lines=35,
show_copy_button=True,
placeholder="Analysis results will appear here after processing..."
)
download_file = gr.File(
label="πŸ“₯ Download Analysis Report",
visible=False
)
# Hidden component to store download content
download_content = gr.Textbox(visible=False)
# Information sections
with gr.Accordion("πŸ’‘ About Gemini Vision Pro", open=False):
gr.Markdown("""
### πŸš€ **Advantages of Gemini Vision Pro:**
- **Fast Processing**: No local model loading - results in seconds
- **Low Resource Usage**: Runs via API calls, minimal local computing needed
- **High Quality**: Google's latest multimodal AI model
- **Always Updated**: Access to the latest model improvements
- **Reliable**: Enterprise-grade infrastructure
### πŸ” **Supported Medical Images:**
- **Radiology**: X-rays, CT scans, MRI images, Ultrasound
- **Pathology**: Histological slides, Cytology specimens
- **Dermatology**: Skin lesions, Rashes, Clinical photos
- **Ophthalmology**: Fundus photos, OCT images
- **Clinical Photography**: Wound assessment, Physical findings
- **Microscopy**: Cellular and tissue analysis
### πŸ’° **Cost Information:**
- Gemini Vision Pro uses pay-per-use pricing
- Typically very affordable for individual analyses
- Check [Google AI Pricing](https://ai.google.dev/pricing) for current rates
""")
with gr.Accordion("πŸ“ Tips for Better Results", open=False):
gr.Markdown("""
### 🎯 **Optimization Tips:**
- **Provide clinical context**: Age, symptoms, and history significantly improve accuracy
- **Use specific focus areas**: "cardiac silhouette, pulmonary vessels" vs just "chest"
- **High-quality images**: Clear, well-lit, properly oriented images work best
- **Appropriate image size**: Gemini works well with various image sizes
- **Choose right analysis type**: Comprehensive for complex cases, Quick for screening
### πŸ” **API Key Security:**
- Your API key is only used for this session and not stored
- Consider using environment variables for production deployments
- Monitor your API usage in Google Cloud Console
""")
# Footer
gr.HTML("""
<div style="text-align: center; margin-top: 20px; padding: 15px; background-color: #fff3cd; border-radius: 8px;">
<strong>⚠️ Medical Disclaimer:</strong> This AI tool is for educational and research purposes only.
It should never replace professional medical diagnosis or treatment.
Always consult qualified healthcare providers for medical decisions.
</div>
""")
# Event handlers
def create_download_file(content):
if content:
filename = f"gemini_medical_analysis_{int(time.time())}.json"
with open(filename, "w") as f:
f.write(content)
return gr.File(value=filename, visible=True)
return gr.File(visible=False)
def test_api_connection(api_key):
if not api_key:
return "⏳ Enter API key to connect"
success, status = setup_gemini(api_key)
return status
# API key testing
api_key_input.change(
fn=test_api_connection,
inputs=[api_key_input],
outputs=[status_display]
)
# Main analysis
analyze_btn.click(
fn=analyze_medical_image_gemini,
inputs=[
image_input, age_input, gender_input, symptoms_input,
history_input, medications_input, analysis_type, focus_areas, api_key_input
],
outputs=[analysis_output, download_content, status_display]
).then(
fn=create_download_file,
inputs=[download_content],
outputs=[download_file]
)
return interface
if __name__ == "__main__":
print("πŸ₯ Initializing Gemini Medical AI Analyzer...")
print("πŸš€ No local model loading required - using Google Gemini Vision Pro API")
# Create and launch interface
interface = create_interface()
# Launch with optimized settings
interface.launch(
server_name="0.0.0.0",
server_port=7860,
share=False,
show_error=True,
quiet=False
)