working wather api connection and first strach of code
This commit is contained in:
parent
7c580845f1
commit
94e676c692
6 changed files with 282 additions and 0 deletions
3
links.txt
Normal file
3
links.txt
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
https://hackathon.bz.it/secure/user
|
||||||
|
https://hackathon.bz.it/login
|
||||||
|
|
BIN
testLLMinteraction1plant/.cache.sqlite
Normal file
BIN
testLLMinteraction1plant/.cache.sqlite
Normal file
Binary file not shown.
7
testLLMinteraction1plant/README.md
Normal file
7
testLLMinteraction1plant/README.md
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
## this app requires:
|
||||||
|
- python >= 3.11.0
|
||||||
|
|
||||||
|
### How to run:
|
||||||
|
- cd inside the root of the project
|
||||||
|
- install all necessary dependencies from the txt by doing : "pip install -r requirements.txt"
|
||||||
|
- run by doing python script.py
|
BIN
testLLMinteraction1plant/foto/basilico.jpg
Normal file
BIN
testLLMinteraction1plant/foto/basilico.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.4 MiB |
11
testLLMinteraction1plant/requirements.txt
Normal file
11
testLLMinteraction1plant/requirements.txt
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
openmeteo-requests
|
||||||
|
pandas
|
||||||
|
torch
|
||||||
|
diffusers
|
||||||
|
transformers
|
||||||
|
pillow
|
||||||
|
requests-cache
|
||||||
|
retry-requests
|
||||||
|
numpy
|
||||||
|
accelerate
|
||||||
|
hf_xet
|
261
testLLMinteraction1plant/script.py
Normal file
261
testLLMinteraction1plant/script.py
Normal file
|
@ -0,0 +1,261 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
"""
|
||||||
|
Complete Plant Prediction Pipeline with Open-Meteo Official Client
|
||||||
|
Open source weather + AI image transformation
|
||||||
|
"""
|
||||||
|
|
||||||
|
import openmeteo_requests
|
||||||
|
import pandas as pd
|
||||||
|
import requests_cache
|
||||||
|
from retry_requests import retry
|
||||||
|
from datetime import datetime, timedelta
|
||||||
|
from PIL import Image
|
||||||
|
import torch
|
||||||
|
from diffusers import StableDiffusionInstructPix2PixPipeline
|
||||||
|
import numpy as np
|
||||||
|
|
||||||
|
class PlantPredictor:
|
||||||
|
def __init__(self):
|
||||||
|
"""Initialize the plant prediction pipeline with Open-Meteo client"""
|
||||||
|
# Setup the Open-Meteo API client with cache and retry on error
|
||||||
|
cache_session = requests_cache.CachedSession('.cache', expire_after=3600)
|
||||||
|
retry_session = retry(cache_session, retries=5, backoff_factor=0.2)
|
||||||
|
self.openmeteo = openmeteo_requests.Client(session=retry_session)
|
||||||
|
|
||||||
|
self.image_model = None
|
||||||
|
|
||||||
|
def load_image_model(self):
|
||||||
|
"""Load the image transformation model"""
|
||||||
|
print("Loading Stable Diffusion model...")
|
||||||
|
self.image_model = StableDiffusionInstructPix2PixPipeline.from_pretrained(
|
||||||
|
"timbrooks/instruct-pix2pix",
|
||||||
|
torch_dtype=torch.float16 if torch.cuda.is_available() else torch.float32
|
||||||
|
)
|
||||||
|
if torch.cuda.is_available():
|
||||||
|
self.image_model = self.image_model.to("cuda")
|
||||||
|
print("Model loaded successfully!")
|
||||||
|
|
||||||
|
def get_weather_forecast(self, lat, lon, days=7):
|
||||||
|
"""Get weather forecast from Open-Meteo API using official client"""
|
||||||
|
|
||||||
|
start_date = datetime.now().strftime("%Y-%m-%d")
|
||||||
|
end_date = (datetime.now() + timedelta(days=days)).strftime("%Y-%m-%d")
|
||||||
|
|
||||||
|
url = "https://api.open-meteo.com/v1/forecast"
|
||||||
|
params = {
|
||||||
|
"latitude": lat,
|
||||||
|
"longitude": lon,
|
||||||
|
"daily": [
|
||||||
|
"temperature_2m_max",
|
||||||
|
"temperature_2m_min",
|
||||||
|
"precipitation_sum",
|
||||||
|
"rain_sum",
|
||||||
|
"uv_index_max",
|
||||||
|
"sunshine_duration"
|
||||||
|
],
|
||||||
|
"start_date": start_date,
|
||||||
|
"end_date": end_date,
|
||||||
|
"timezone": "auto"
|
||||||
|
}
|
||||||
|
|
||||||
|
try:
|
||||||
|
responses = self.openmeteo.weather_api(url, params=params)
|
||||||
|
response = responses[0] # Process first location
|
||||||
|
|
||||||
|
print(f"Coordinates: {response.Latitude()}°N {response.Longitude()}°E")
|
||||||
|
print(f"Elevation: {response.Elevation()} m asl")
|
||||||
|
print(f"Timezone: UTC{response.UtcOffsetSeconds()//3600:+d}")
|
||||||
|
|
||||||
|
# Process daily data
|
||||||
|
daily = response.Daily()
|
||||||
|
|
||||||
|
# Extract data as numpy arrays (much faster!)
|
||||||
|
daily_data = {
|
||||||
|
"date": pd.date_range(
|
||||||
|
start=pd.to_datetime(daily.Time(), unit="s", utc=True),
|
||||||
|
end=pd.to_datetime(daily.TimeEnd(), unit="s", utc=True),
|
||||||
|
freq=pd.Timedelta(seconds=daily.Interval()),
|
||||||
|
inclusive="left"
|
||||||
|
),
|
||||||
|
"temperature_2m_max": daily.Variables(0).ValuesAsNumpy(),
|
||||||
|
"temperature_2m_min": daily.Variables(1).ValuesAsNumpy(),
|
||||||
|
"precipitation_sum": daily.Variables(2).ValuesAsNumpy(),
|
||||||
|
"rain_sum": daily.Variables(3).ValuesAsNumpy(),
|
||||||
|
"uv_index_max": daily.Variables(4).ValuesAsNumpy(),
|
||||||
|
"sunshine_duration": daily.Variables(5).ValuesAsNumpy()
|
||||||
|
}
|
||||||
|
|
||||||
|
# Create DataFrame for easy analysis
|
||||||
|
daily_dataframe = pd.DataFrame(data=daily_data)
|
||||||
|
|
||||||
|
return daily_dataframe, response
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Error fetching weather data: {e}")
|
||||||
|
return None, None
|
||||||
|
|
||||||
|
def analyze_weather_for_plants(self, weather_df):
|
||||||
|
"""Analyze weather data and create plant-specific metrics"""
|
||||||
|
|
||||||
|
if weather_df is None or weather_df.empty:
|
||||||
|
return None
|
||||||
|
|
||||||
|
# Handle NaN values by filling with 0 or mean
|
||||||
|
weather_df = weather_df.fillna(0)
|
||||||
|
|
||||||
|
# Calculate plant-relevant metrics using pandas (more efficient)
|
||||||
|
plant_conditions = {
|
||||||
|
"avg_temp_max": round(weather_df['temperature_2m_max'].mean(), 1),
|
||||||
|
"avg_temp_min": round(weather_df['temperature_2m_min'].mean(), 1),
|
||||||
|
"total_precipitation": round(weather_df['precipitation_sum'].sum(), 1),
|
||||||
|
"total_rain": round(weather_df['rain_sum'].sum(), 1),
|
||||||
|
"total_sunshine_hours": round(weather_df['sunshine_duration'].sum() / 3600, 1), # Convert to hours
|
||||||
|
"max_uv_index": round(weather_df['uv_index_max'].max(), 1),
|
||||||
|
"days_analyzed": len(weather_df),
|
||||||
|
"temp_range": round(weather_df['temperature_2m_max'].max() - weather_df['temperature_2m_min'].min(), 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
return plant_conditions
|
||||||
|
|
||||||
|
def create_transformation_prompt(self, plant_conditions):
|
||||||
|
"""Create a detailed prompt for image transformation based on weather"""
|
||||||
|
|
||||||
|
if not plant_conditions:
|
||||||
|
return "Show this plant after one week of growth"
|
||||||
|
|
||||||
|
# Analyze conditions and create descriptive prompt
|
||||||
|
temp_avg = (plant_conditions['avg_temp_max'] + plant_conditions['avg_temp_min']) / 2
|
||||||
|
|
||||||
|
# Temperature effects
|
||||||
|
if temp_avg > 25:
|
||||||
|
temp_effect = "warm weather promoting vigorous growth with larger, darker green leaves"
|
||||||
|
elif temp_avg < 10:
|
||||||
|
temp_effect = "cool weather slowing growth with smaller, pale leaves"
|
||||||
|
else:
|
||||||
|
temp_effect = "moderate temperature supporting steady growth with healthy green foliage"
|
||||||
|
|
||||||
|
# Water effects
|
||||||
|
if plant_conditions['total_rain'] > 20:
|
||||||
|
water_effect = "abundant rainfall keeping leaves lush, turgid and deep green"
|
||||||
|
elif plant_conditions['total_rain'] < 5:
|
||||||
|
water_effect = "dry conditions causing slight leaf wilting and browning at edges"
|
||||||
|
else:
|
||||||
|
water_effect = "adequate moisture maintaining crisp, healthy leaf appearance"
|
||||||
|
|
||||||
|
# Sunlight effects
|
||||||
|
if plant_conditions['total_sunshine_hours'] > 50:
|
||||||
|
sun_effect = "plenty of sunlight encouraging dense, compact foliage growth"
|
||||||
|
elif plant_conditions['total_sunshine_hours'] < 20:
|
||||||
|
sun_effect = "limited sunlight causing elongated stems and sparse leaf growth"
|
||||||
|
else:
|
||||||
|
sun_effect = "moderate sunlight supporting balanced, proportional growth"
|
||||||
|
|
||||||
|
# UV effects
|
||||||
|
if plant_conditions['max_uv_index'] > 7:
|
||||||
|
uv_effect = "high UV causing slight leaf thickening and waxy appearance"
|
||||||
|
else:
|
||||||
|
uv_effect = "moderate UV maintaining normal leaf texture"
|
||||||
|
|
||||||
|
prompt = f"""Transform this plant showing realistic growth after {plant_conditions['days_analyzed']} days with {temp_effect}, {water_effect}, {sun_effect}, and {uv_effect}. Show natural changes in leaf size, color saturation, stem thickness, and overall plant structure. Weather summary: {plant_conditions['avg_temp_min']}-{plant_conditions['avg_temp_max']}°C, {plant_conditions['total_rain']}mm rain, {plant_conditions['total_sunshine_hours']}h sun"""
|
||||||
|
|
||||||
|
return prompt
|
||||||
|
|
||||||
|
def transform_plant_image(self, image_path, prompt, num_inference_steps=20):
|
||||||
|
"""Transform plant image based on weather conditions"""
|
||||||
|
|
||||||
|
if self.image_model is None:
|
||||||
|
self.load_image_model()
|
||||||
|
|
||||||
|
try:
|
||||||
|
# Load and prepare image
|
||||||
|
image = Image.open(image_path).convert("RGB")
|
||||||
|
|
||||||
|
# Resize if too large (for memory efficiency)
|
||||||
|
if max(image.size) > 1024:
|
||||||
|
image.thumbnail((1024, 1024), Image.Resampling.LANCZOS)
|
||||||
|
|
||||||
|
# Transform image
|
||||||
|
print(f"Transforming image with prompt: {prompt}")
|
||||||
|
result = self.image_model(
|
||||||
|
prompt,
|
||||||
|
image=image,
|
||||||
|
num_inference_steps=num_inference_steps,
|
||||||
|
image_guidance_scale=1.5,
|
||||||
|
guidance_scale=7.5
|
||||||
|
).images[0]
|
||||||
|
|
||||||
|
return result
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Error transforming image: {e}")
|
||||||
|
return None
|
||||||
|
|
||||||
|
def predict_plant_growth(self, image_path, lat, lon, output_path="predicted_plant.jpg", days=7):
|
||||||
|
"""Complete pipeline: weather + image transformation"""
|
||||||
|
|
||||||
|
print(f"Starting plant prediction for coordinates: {lat}, {lon}")
|
||||||
|
print(f"Analyzing {days} days of weather data...")
|
||||||
|
|
||||||
|
# Step 1: Get weather data using official Open-Meteo client
|
||||||
|
print("Fetching weather data with caching and retry...")
|
||||||
|
weather_df, response_info = self.get_weather_forecast(lat, lon, days)
|
||||||
|
|
||||||
|
if weather_df is None:
|
||||||
|
print("Failed to get weather data")
|
||||||
|
return None
|
||||||
|
|
||||||
|
print(f"Weather data retrieved for {len(weather_df)} days")
|
||||||
|
print("\nWeather Overview:")
|
||||||
|
print(weather_df[['date', 'temperature_2m_max', 'temperature_2m_min', 'precipitation_sum', 'sunshine_duration']].head())
|
||||||
|
|
||||||
|
# Step 2: Analyze weather for plants
|
||||||
|
plant_conditions = self.analyze_weather_for_plants(weather_df)
|
||||||
|
print(f"\nPlant-specific weather analysis: {plant_conditions}")
|
||||||
|
|
||||||
|
# Step 3: Create transformation prompt
|
||||||
|
prompt = self.create_transformation_prompt(plant_conditions)
|
||||||
|
print(f"\nGenerated transformation prompt: {prompt}")
|
||||||
|
|
||||||
|
# Step 4: Transform image
|
||||||
|
print("\nTransforming plant image...")
|
||||||
|
result_image = self.transform_plant_image(image_path, prompt)
|
||||||
|
|
||||||
|
if result_image:
|
||||||
|
result_image.save(output_path)
|
||||||
|
print(f"Plant growth prediction saved to: {output_path}")
|
||||||
|
return result_image, plant_conditions, weather_df
|
||||||
|
else:
|
||||||
|
print("Failed to transform image")
|
||||||
|
return None
|
||||||
|
|
||||||
|
# Example usage
|
||||||
|
if __name__ == "__main__":
|
||||||
|
# Initialize predictor
|
||||||
|
predictor = PlantPredictor()
|
||||||
|
|
||||||
|
# Example coordinates (Milan, Italy)
|
||||||
|
latitude = 45.4642
|
||||||
|
longitude = 9.1900
|
||||||
|
|
||||||
|
# Predict plant growth
|
||||||
|
# Replace 'your_plant_image.jpg' with actual image path
|
||||||
|
result = predictor.predict_plant_growth(
|
||||||
|
image_path=r"./foto/basilico.jpg",
|
||||||
|
lat=latitude,
|
||||||
|
lon=longitude,
|
||||||
|
output_path=r"./predicted_plant_growth.jpg",
|
||||||
|
days=7
|
||||||
|
)
|
||||||
|
|
||||||
|
if result:
|
||||||
|
image, conditions, weather_data = result
|
||||||
|
print("\n" + "="*50)
|
||||||
|
print("PLANT PREDICTION COMPLETED SUCCESSFULLY!")
|
||||||
|
print("="*50)
|
||||||
|
print(f"Weather conditions analyzed: {conditions}")
|
||||||
|
print(f"Weather data shape: {weather_data.shape}")
|
||||||
|
print(f"Temperature range: {conditions['avg_temp_min']}°C to {conditions['avg_temp_max']}°C")
|
||||||
|
print(f"Total precipitation: {conditions['total_rain']}mm")
|
||||||
|
print(f"Sunshine hours: {conditions['total_sunshine_hours']}h")
|
||||||
|
else:
|
||||||
|
print("Plant prediction failed.")
|
Loading…
Add table
Add a link
Reference in a new issue