File size: 9,226 Bytes
5acf918
 
 
 
 
 
 
 
 
 
 
29c09b0
5acf918
 
 
 
 
 
 
 
 
 
 
29c09b0
5acf918
 
 
 
 
 
 
 
 
 
29c09b0
5acf918
29c09b0
5acf918
 
29c09b0
5acf918
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
29c09b0
5acf918
 
29c09b0
5acf918
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
29c09b0
5acf918
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
29c09b0
5acf918
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9a8f282
 
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
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()