diff --git a/links.txt b/links.txt new file mode 100644 index 0000000..452b0a0 --- /dev/null +++ b/links.txt @@ -0,0 +1,3 @@ +https://hackathon.bz.it/secure/user +https://hackathon.bz.it/login + diff --git a/testLLMinteraction1plant/.cache.sqlite b/testLLMinteraction1plant/.cache.sqlite new file mode 100644 index 0000000..c591b13 Binary files /dev/null and b/testLLMinteraction1plant/.cache.sqlite differ diff --git a/testLLMinteraction1plant/README.md b/testLLMinteraction1plant/README.md new file mode 100644 index 0000000..4710913 --- /dev/null +++ b/testLLMinteraction1plant/README.md @@ -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 \ No newline at end of file diff --git a/testLLMinteraction1plant/foto/basilico.jpg b/testLLMinteraction1plant/foto/basilico.jpg new file mode 100644 index 0000000..d84b39d Binary files /dev/null and b/testLLMinteraction1plant/foto/basilico.jpg differ diff --git a/testLLMinteraction1plant/requirements.txt b/testLLMinteraction1plant/requirements.txt new file mode 100644 index 0000000..2a0635e --- /dev/null +++ b/testLLMinteraction1plant/requirements.txt @@ -0,0 +1,11 @@ +openmeteo-requests +pandas +torch +diffusers +transformers +pillow +requests-cache +retry-requests +numpy +accelerate +hf_xet \ No newline at end of file diff --git a/testLLMinteraction1plant/script.py b/testLLMinteraction1plant/script.py new file mode 100644 index 0000000..4af22c2 --- /dev/null +++ b/testLLMinteraction1plant/script.py @@ -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.") \ No newline at end of file