#!/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("""
Fast, efficient medical image analysis using Google's latest AI