import gradio as gr import os from openai import OpenAI import json import requests from PIL import Image import io import base64 # Constants DEFAULT_MODEL = "opengvlab/internvl3-14b:free" # No need for placeholder text as we'll use password type input DEFAULT_SITE_URL = "https://dynamic-nature-trail-guide.app" DEFAULT_SITE_NAME = "Dynamic Nature Trail Guide" # Initialize system prompt for better nature guide responses SYSTEM_PROMPT = """ You are the Dynamic Nature Trail Guide, an expert in identifying and explaining natural elements found on nature trails. For any image sent, please: 1. Identify all visible plants, animals, geological features, and ecosystems 2. Provide educational information about identified elements 3. Mention any seasonal characteristics visible in the image 4. Note any ecological significance or conservation considerations 5. Offer suggestions for what to observe or learn about next on the trail Keep explanations informative yet accessible to people of all ages and backgrounds. """ def encode_image_to_base64(image_path): """Convert an image file to base64 encoding""" with open(image_path, "rb") as image_file: return base64.b64encode(image_file.read()).decode('utf-8') def analyze_image(api_key, image, prompt="What can you identify in this nature trail image? Provide detailed educational information.", site_url=DEFAULT_SITE_URL, site_name=DEFAULT_SITE_NAME, model=DEFAULT_MODEL): """Analyze the uploaded image using the InternVL3 model via OpenRouter""" # Remove the placeholder text check if not api_key: return "Please provide an OpenRouter API key." if image is None: return "Please upload an image to analyze." # Save the image temporarily temp_image_path = "temp_image.jpg" image.save(temp_image_path) try: # Convert image to base64 base64_image = encode_image_to_base64(temp_image_path) # Initialize OpenAI client client = OpenAI( base_url="https://openrouter.ai/api/v1", api_key=api_key, ) # Create message with image and text response = client.chat.completions.create( extra_headers={ "HTTP-Referer": site_url, "X-Title": site_name, }, model=model, messages=[ {"role": "system", "content": SYSTEM_PROMPT}, { "role": "user", "content": [ { "type": "text", "text": prompt }, { "type": "image_url", "image_url": { "url": f"data:image/jpeg;base64,{base64_image}" } } ] } ] ) analysis_result = response.choices[0].message.content return analysis_result except Exception as e: return f"Error analyzing image: {str(e)}" finally: # Clean up the temporary file if os.path.exists(temp_image_path): os.remove(temp_image_path) def build_custom_prompt(identification=True, education=True, seasonal=True, conservation=True, suggestions=True, additional_prompt=""): """Build a custom prompt based on user preferences""" prompt_parts = [] if identification: prompt_parts.append("Identify all visible plants, animals, geological features, and ecosystems") if education: prompt_parts.append("Provide educational information about identified elements") if seasonal: prompt_parts.append("Mention any seasonal characteristics visible in the image") if conservation: prompt_parts.append("Note any ecological significance or conservation considerations") if suggestions: prompt_parts.append("Offer suggestions for what to observe or learn next on the trail") if additional_prompt: prompt_parts.append(additional_prompt) if not prompt_parts: return "What can you identify in this nature trail image?" numbered_prompt = "\n".join([f"{i+1}. {part}" for i, part in enumerate(prompt_parts)]) return f"For this nature trail image, please: \n{numbered_prompt}" def create_interface(): """Create the Gradio interface for the Dynamic Nature Trail Guide""" with gr.Blocks(title="Dynamic Nature Trail Guide", theme=gr.themes.Soft()) as app: gr.Markdown(""" # 🌿 Dynamic Nature Trail Guide: Accessible Outdoor Education 🌿 Upload an image from your nature walk to identify plants, animals, geological features, and learn about the ecosystem. This application uses the advanced InternVL3 14B multimodal model for nature identification and education. """) with gr.Row(): with gr.Column(scale=1): api_key_input = gr.Textbox( label="OpenRouter API Key", placeholder="Enter your OpenRouter API key here...", type="password" ) image_input = gr.Image(label="Upload Nature Image", type="pil") with gr.Accordion("Advanced Settings", open=False): site_url = gr.Textbox( label="Site URL (for OpenRouter)", value=DEFAULT_SITE_URL ) site_name = gr.Textbox( label="Site Name (for OpenRouter)", value=DEFAULT_SITE_NAME ) model_selection = gr.Dropdown( label="Model", choices=[DEFAULT_MODEL], value=DEFAULT_MODEL ) with gr.Accordion("Customize Analysis", open=False): gr.Markdown("Select what information you want to receive about the image:") identification_checkbox = gr.Checkbox(label="Species & Feature Identification", value=True) education_checkbox = gr.Checkbox(label="Educational Information", value=True) seasonal_checkbox = gr.Checkbox(label="Seasonal Characteristics", value=True) conservation_checkbox = gr.Checkbox(label="Conservation Considerations", value=True) suggestions_checkbox = gr.Checkbox(label="Trail Suggestions", value=True) additional_prompt = gr.Textbox(label="Additional Instructions (Optional)") analyze_button = gr.Button("Analyze Nature Image", variant="primary") with gr.Column(scale=1): output_text = gr.Markdown(label="Analysis Results") # Set up the click event for the analyze button analyze_button.click( fn=lambda api_key, image, id_check, edu_check, season_check, conserve_check, suggest_check, add_prompt, site_url, site_name, model: analyze_image( api_key, image, build_custom_prompt(id_check, edu_check, season_check, conserve_check, suggest_check, add_prompt), site_url, site_name, model ), inputs=[ api_key_input, image_input, identification_checkbox, education_checkbox, seasonal_checkbox, conservation_checkbox, suggestions_checkbox, additional_prompt, site_url, site_name, model_selection ], outputs=output_text ) # Example gallery with gr.Accordion("Example Images", open=False): gr.Markdown("Click on an example image to analyze it:") example_images = gr.Examples( examples=[ "examples/forest_trail.jpg", "examples/wetland_boardwalk.jpg", "examples/mountain_vista.jpg", "examples/coastal_trail.jpg", ], inputs=image_input, label="Nature Trail Examples" ) gr.Markdown(""" ## How to Use This App 1. Enter your OpenRouter API key (sign up at [openrouter.ai](https://openrouter.ai) if needed) 2. Upload an image from your nature walk 3. Customize what kind of information you want (optional) 4. Click "Analyze Nature Image" 5. Explore the detailed educational content about what you're seeing This application is designed to make nature more accessible and educational for everyone! """) return app # Create and launch the app if __name__ == "__main__": app = create_interface() app.launch()