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() |