Spaces:
Sleeping
Sleeping
File size: 18,255 Bytes
123160d deed5ef 123160d deed5ef 123160d deed5ef 123160d deed5ef 123160d deed5ef 123160d deed5ef 123160d deed5ef 123160d deed5ef 123160d deed5ef 123160d deed5ef 123160d deed5ef 123160d deed5ef 123160d deed5ef 123160d deed5ef 123160d deed5ef 123160d deed5ef 123160d deed5ef 123160d deed5ef 123160d deed5ef 123160d deed5ef 123160d deed5ef 123160d deed5ef 123160d deed5ef 123160d deed5ef 123160d deed5ef 123160d deed5ef 123160d deed5ef 123160d deed5ef 123160d deed5ef 123160d deed5ef 123160d deed5ef 123160d deed5ef 123160d deed5ef 123160d deed5ef 123160d deed5ef 123160d deed5ef 123160d deed5ef 123160d deed5ef 123160d deed5ef 123160d deed5ef 123160d deed5ef 123160d deed5ef 123160d deed5ef 123160d deed5ef 123160d deed5ef 123160d deed5ef 123160d deed5ef 123160d deed5ef 123160d deed5ef 123160d deed5ef 123160d deed5ef 123160d deed5ef 123160d deed5ef 123160d deed5ef 123160d deed5ef 123160d deed5ef 123160d deed5ef 123160d deed5ef 123160d deed5ef 123160d deed5ef 123160d deed5ef |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 |
#!/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
) |