upload image adjustment
This commit is contained in:
parent
179bb5eb44
commit
2b2509dcfd
6 changed files with 233 additions and 62 deletions
BIN
.cache.sqlite
Normal file
BIN
.cache.sqlite
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Before Width: | Height: | Size: 92 KiB |
BIN
test2/predicted_plant_ultra_hq.jpg
Normal file
BIN
test2/predicted_plant_ultra_hq.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 481 KiB |
BIN
test2/predicted_plant_ultra_hq_comparison.jpg
Normal file
BIN
test2/predicted_plant_ultra_hq_comparison.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 264 KiB |
295
test2/script.py
295
test2/script.py
|
@ -36,15 +36,42 @@ class PlantPredictor:
|
|||
self.image_model = None
|
||||
|
||||
def load_image_model(self):
|
||||
"""Load the image transformation model"""
|
||||
print("Loading Stable Diffusion model...")
|
||||
"""Load the image transformation model with high-quality settings"""
|
||||
print("🔄 Loading Stable Diffusion model with high-quality settings...")
|
||||
|
||||
# Check if CUDA is available and print GPU info
|
||||
if torch.cuda.is_available():
|
||||
gpu_name = torch.cuda.get_device_name(0)
|
||||
gpu_memory = torch.cuda.get_device_properties(0).total_memory / 1024**3
|
||||
print(f"🚀 GPU: {gpu_name} ({gpu_memory:.1f} GB)")
|
||||
|
||||
self.image_model = StableDiffusionInstructPix2PixPipeline.from_pretrained(
|
||||
"timbrooks/instruct-pix2pix",
|
||||
torch_dtype=torch.float16 if torch.cuda.is_available() else torch.float32
|
||||
torch_dtype=torch.float16 if torch.cuda.is_available() else torch.float32,
|
||||
use_safetensors=True,
|
||||
safety_checker=None,
|
||||
requires_safety_checker=False
|
||||
)
|
||||
|
||||
if torch.cuda.is_available():
|
||||
self.image_model = self.image_model.to("cuda")
|
||||
print("Model loaded successfully!")
|
||||
|
||||
# Enable memory efficient attention for better quality
|
||||
try:
|
||||
self.image_model.enable_xformers_memory_efficient_attention()
|
||||
print("✅ XFormers memory efficient attention enabled")
|
||||
except:
|
||||
print("⚠️ XFormers not available, using standard attention")
|
||||
|
||||
# Enable VAE slicing for higher resolution support
|
||||
self.image_model.enable_vae_slicing()
|
||||
print("✅ VAE slicing enabled for high-res support")
|
||||
|
||||
# Enable attention slicing for memory efficiency
|
||||
self.image_model.enable_attention_slicing(1)
|
||||
print("✅ Attention slicing enabled")
|
||||
|
||||
print("✅ High-quality model loaded successfully!")
|
||||
|
||||
def get_weather_forecast(self, lat, lon, days=7):
|
||||
"""Get weather forecast from Open-Meteo API using official client"""
|
||||
|
@ -242,93 +269,219 @@ class PlantPredictor:
|
|||
else:
|
||||
return "showing some stress"
|
||||
|
||||
def transform_plant_image(self, image_path, prompt):
|
||||
"""STEP 4: Generate new image based on analyzed prompt"""
|
||||
def transform_plant_image(self, image_path, prompt, num_samples=1):
|
||||
"""STEP 4: Generate ULTRA HIGH-QUALITY image with 60 inference steps"""
|
||||
|
||||
if self.image_model is None:
|
||||
self.load_image_model()
|
||||
|
||||
try:
|
||||
# Load and prepare image
|
||||
# Load and prepare image with HIGHER RESOLUTION
|
||||
print(f"📸 Loading image for high-quality processing: {image_path}")
|
||||
image = Image.open(image_path).convert("RGB")
|
||||
original_size = image.size
|
||||
|
||||
# Resize if too large (for memory efficiency)
|
||||
if max(image.size) > 1024:
|
||||
image.thumbnail((1024, 1024), Image.Resampling.LANCZOS)
|
||||
# Use HIGHER resolution for better quality (up to 1024x1024)
|
||||
max_size = 1024 # Increased from 512 for better quality
|
||||
if max(image.size) < max_size:
|
||||
# Upscale smaller images for better quality
|
||||
scale_factor = max_size / max(image.size)
|
||||
new_size = (int(image.size[0] * scale_factor), int(image.size[1] * scale_factor))
|
||||
image = image.resize(new_size, Image.Resampling.LANCZOS)
|
||||
print(f"📈 Upscaled image from {original_size} to {image.size} for better quality")
|
||||
elif max(image.size) > max_size:
|
||||
# Resize but maintain higher resolution
|
||||
image.thumbnail((max_size, max_size), Image.Resampling.LANCZOS)
|
||||
print(f"📏 Resized image from {original_size} to {image.size}")
|
||||
|
||||
print(f" STEP 4: Generating transformed image...")
|
||||
print(f" Using prompt: {prompt}")
|
||||
print(f"🎨 Generating 1 ULTRA HIGH-QUALITY sample with 60 inference steps...")
|
||||
print(f"📝 Using enhanced prompt: {prompt[:120]}...")
|
||||
|
||||
# Transform image
|
||||
result = self.image_model(
|
||||
prompt,
|
||||
image=image,
|
||||
num_inference_steps=20,
|
||||
image_guidance_scale=1.5,
|
||||
guidance_scale=7.5
|
||||
).images[0]
|
||||
generated_images = []
|
||||
|
||||
return result
|
||||
# Clear GPU cache before generation
|
||||
if torch.cuda.is_available():
|
||||
torch.cuda.empty_cache()
|
||||
|
||||
for i in range(num_samples):
|
||||
print(f"🔄 Generating ultra high-quality sample {i+1}/{num_samples} with 60 steps...")
|
||||
|
||||
# Use different seeds for variety
|
||||
seed = 42 + i * 137 # Prime number spacing for better variety
|
||||
generator = torch.Generator(device="cuda" if torch.cuda.is_available() else "cpu").manual_seed(seed)
|
||||
|
||||
# ULTRA HIGH-QUALITY SETTINGS (60 steps for maximum quality)
|
||||
result = self.image_model(
|
||||
prompt,
|
||||
image=image,
|
||||
num_inference_steps=40, # Increased to 60 for ultra high quality
|
||||
image_guidance_scale=2.0, # Increased from 1.5 for stronger conditioning
|
||||
guidance_scale=9.0, # Increased from 7.5 for better prompt following
|
||||
generator=generator,
|
||||
eta=0.0, # Deterministic for better quality
|
||||
# Add additional quality parameters
|
||||
).images[0]
|
||||
|
||||
generated_images.append(result)
|
||||
print(f"✅ Ultra high-quality sample {i+1} completed with 60 inference steps!")
|
||||
|
||||
# Clean up GPU memory between generations
|
||||
if torch.cuda.is_available():
|
||||
torch.cuda.empty_cache()
|
||||
|
||||
print(f"🎉 Ultra high-quality sample generated with 60 inference steps!")
|
||||
return generated_images
|
||||
|
||||
except torch.cuda.OutOfMemoryError:
|
||||
print("❌ GPU out of memory! Try reducing num_samples or image resolution")
|
||||
print("💡 Current settings are optimized for high-end GPUs")
|
||||
if torch.cuda.is_available():
|
||||
torch.cuda.empty_cache()
|
||||
return None
|
||||
except Exception as e:
|
||||
print(f"Error transforming image: {e}")
|
||||
print(f"❌ Error transforming image: {e}")
|
||||
if torch.cuda.is_available():
|
||||
torch.cuda.empty_cache()
|
||||
return None
|
||||
|
||||
def predict_plant_growth(self, image_path, lat=None, lon=None, output_path="predicted_plant.jpg", days=7):
|
||||
"""Complete pipeline: weather + image transformation"""
|
||||
def predict_plant_growth(self, image_path, lat=None, lon=None, output_path="predicted_plant.jpg", days=7, num_samples=1, high_quality=True):
|
||||
"""Complete ULTRA HIGH-QUALITY pipeline with 60 inference steps for maximum quality"""
|
||||
|
||||
# Auto-detect location if not provided
|
||||
if lat is None or lon is None:
|
||||
print(" Auto-detecting location...")
|
||||
print("🌍 Auto-detecting location...")
|
||||
lat, lon = self.get_current_location()
|
||||
|
||||
print(f" Starting plant prediction for coordinates: {lat:.4f}, {lon:.4f}")
|
||||
print(f" Analyzing {days} days of weather data...")
|
||||
print(f"🌱 Starting ULTRA HIGH-QUALITY plant prediction for coordinates: {lat:.4f}, {lon:.4f}")
|
||||
print(f"📅 Analyzing {days} days of weather data...")
|
||||
print(f"🎯 Generating 1 ultra high-quality sample with 60 inference steps")
|
||||
print(f"⚠️ This will take longer but produce maximum quality results")
|
||||
|
||||
# Step 1: Get weather data using official Open-Meteo client
|
||||
print("Fetching weather data with caching and retry...")
|
||||
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")
|
||||
print("❌ Failed to get weather data")
|
||||
return None
|
||||
|
||||
print(f"Weather data retrieved for {len(weather_df)} days")
|
||||
print("\nWeather Overview:")
|
||||
print(f"✅ Weather data retrieved for {len(weather_df)} days")
|
||||
print("\n📊 Weather 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}")
|
||||
print(f"\n🔬 Plant-specific weather analysis: {plant_conditions}")
|
||||
|
||||
# Step 3: Analyze image + weather to create intelligent prompt
|
||||
print("\n STEP 3: Analyzing image and creating transformation prompt...")
|
||||
print("\n🧠 STEP 3: Advanced image analysis and prompt creation...")
|
||||
try:
|
||||
prompt, plant_type, plant_health = self.create_transformation_prompt(image_path, plant_conditions)
|
||||
print(f" Plant identified as: {plant_type}")
|
||||
print(f" Current health: {plant_health}")
|
||||
print(f" Generated transformation prompt: {prompt}")
|
||||
print(f"🌿 Plant identified as: {plant_type}")
|
||||
print(f"💚 Current health: {plant_health}")
|
||||
print(f"📝 Enhanced transformation prompt: {prompt}")
|
||||
except Exception as e:
|
||||
print(f" Error in Step 3: {e}")
|
||||
print(f"❌ Error in Step 3: {e}")
|
||||
return None
|
||||
|
||||
# Step 4: Generate transformed image
|
||||
print("\nSTEP 4: Generating prediction image...")
|
||||
# Step 4: Generate ULTRA HIGH-QUALITY transformed image
|
||||
print(f"\n STEP 4: Generating 1 prediction with 60 inference steps...")
|
||||
print(" This may take 5-8 minutes for absolute maximum quality...")
|
||||
|
||||
import time
|
||||
start_time = time.time()
|
||||
|
||||
try:
|
||||
result_image = self.transform_plant_image(image_path, prompt)
|
||||
result_images = self.transform_plant_image(image_path, prompt, num_samples=num_samples)
|
||||
except Exception as e:
|
||||
print(f" Error in Step 4: {e}")
|
||||
return None
|
||||
|
||||
if result_image:
|
||||
result_image.save(output_path)
|
||||
print(f"Plant growth prediction saved to: {output_path}")
|
||||
return result_image, plant_conditions, weather_df, plant_type, plant_health
|
||||
end_time = time.time()
|
||||
total_time = end_time - start_time
|
||||
|
||||
if result_images and len(result_images) > 0:
|
||||
# Save the ultra high-quality result
|
||||
saved_paths = []
|
||||
|
||||
# Save with maximum quality JPEG settings
|
||||
result_images[0].save(output_path, "JPEG", quality=98, optimize=True)
|
||||
saved_paths.append(output_path)
|
||||
print(f" prediction saved to: {output_path}")
|
||||
|
||||
# Create comparison with original
|
||||
self.create_comparison_grid(image_path, result_images, f"{output_path.replace('.jpg', '')}_comparison.jpg")
|
||||
|
||||
print(f"⏱️ Total generation time: {total_time:.1f} seconds")
|
||||
print(f"🏆 Generated with 60 inference steps for maximum quality!")
|
||||
|
||||
# GPU memory usage info
|
||||
if torch.cuda.is_available():
|
||||
memory_used = torch.cuda.max_memory_allocated() / 1024**3
|
||||
print(f" Peak GPU memory usage: {memory_used:.2f} GB")
|
||||
torch.cuda.reset_peak_memory_stats()
|
||||
|
||||
return result_images, plant_conditions, weather_df, plant_type, plant_health, saved_paths
|
||||
else:
|
||||
print("Failed to transform image")
|
||||
print(" Failed to generate image")
|
||||
return None
|
||||
|
||||
def create_comparison_grid(self, original_path, generated_images, output_path):
|
||||
"""Create a comparison grid"""
|
||||
try:
|
||||
from PIL import Image, ImageDraw, ImageFont
|
||||
|
||||
# Load original
|
||||
original = Image.open(original_path).convert("RGB")
|
||||
|
||||
# Use higher resolution for grid
|
||||
target_size = (512, 512)
|
||||
original = original.resize(target_size, Image.Resampling.LANCZOS)
|
||||
resized_generated = [img.resize(target_size, Image.Resampling.LANCZOS) for img in generated_images]
|
||||
|
||||
# Calculate grid
|
||||
total_images = len(generated_images) + 1
|
||||
cols = min(3, total_images) # 3 columns max for better layout
|
||||
rows = (total_images + cols - 1) // cols
|
||||
|
||||
# Create high-quality grid
|
||||
grid_width = cols * target_size[0]
|
||||
grid_height = rows * target_size[1] + 80 # More space for labels
|
||||
grid_image = Image.new('RGB', (grid_width, grid_height), 'white')
|
||||
|
||||
# Add images
|
||||
grid_image.paste(original, (0, 80))
|
||||
for i, img in enumerate(resized_generated):
|
||||
col = (i + 1) % cols
|
||||
row = (i + 1) // cols
|
||||
x = col * target_size[0]
|
||||
y = row * target_size[1] + 80
|
||||
grid_image.paste(img, (x, y))
|
||||
|
||||
# Add labels
|
||||
try:
|
||||
draw = ImageDraw.Draw(grid_image)
|
||||
try:
|
||||
font = ImageFont.truetype("arial.ttf", 32) # Larger font
|
||||
except:
|
||||
font = ImageFont.load_default()
|
||||
|
||||
draw.text((10, 20), "Original", fill='black', font=font)
|
||||
for i in range(len(resized_generated)):
|
||||
col = (i + 1) % cols
|
||||
x = col * target_size[0] + 10
|
||||
draw.text((x, 20), f"HQ Sample {i+1}", fill='black', font=font)
|
||||
except:
|
||||
pass
|
||||
|
||||
# Save with high quality
|
||||
grid_image.save(output_path, "JPEG", quality=95, optimize=True)
|
||||
print(f" High-quality comparison grid saved to: {output_path}")
|
||||
|
||||
except Exception as e:
|
||||
print(f" Could not create comparison grid: {e}")
|
||||
|
||||
# Example usage
|
||||
# Example usage - HIGH QUALITY MODE
|
||||
if __name__ == "__main__":
|
||||
# Initialize predictor
|
||||
predictor = PlantPredictor()
|
||||
|
@ -337,27 +490,45 @@ if __name__ == "__main__":
|
|||
latitude = 45.4642
|
||||
longitude = 9.1900
|
||||
|
||||
# Predict plant growth
|
||||
# Replace 'your_plant_image.jpg' with actual image path
|
||||
print(" Starting ULTRA HIGH-QUALITY plant prediction with 60 inference steps...")
|
||||
print(" This will use maximum GPU power and time for absolute best quality")
|
||||
|
||||
# Ultra high-quality prediction with single sample
|
||||
result = predictor.predict_plant_growth(
|
||||
image_path="./foto/basilico.jpg",
|
||||
lat=latitude,
|
||||
lon=longitude,
|
||||
output_path="./predicted_plant_growth.jpg",
|
||||
days=7
|
||||
output_path="./predicted_plant_ultra_hq.jpg",
|
||||
days=7,
|
||||
num_samples=1, # Single ultra high-quality sample
|
||||
high_quality=True
|
||||
)
|
||||
|
||||
if result:
|
||||
image, conditions, weather_data, plant_type, plant_health = result
|
||||
print("\n" + "="*50)
|
||||
print(" PLANT PREDICTION COMPLETED SUCCESSFULLY!")
|
||||
print("="*50)
|
||||
print(f" Plant type: {plant_type}")
|
||||
print(f" Plant health: {plant_health}")
|
||||
print(f" Weather conditions: {conditions}")
|
||||
print(f" Data points: {weather_data.shape}")
|
||||
print(f" Temperature: {conditions['avg_temp_min']}°C to {conditions['avg_temp_max']}°C")
|
||||
print(f" Total rain: {conditions['total_rain']}mm")
|
||||
print(f" Sunshine: {conditions['total_sunshine_hours']}h")
|
||||
images, conditions, weather_data, plant_type, plant_health, saved_paths = result
|
||||
print("\n" + "="*60)
|
||||
print("🎉 PLANT PREDICTION COMPLETED!")
|
||||
print("="*60)
|
||||
print(f"🌿 Plant type: {plant_type}")
|
||||
print(f"💚 Plant health: {plant_health}")
|
||||
print(f"🎯 Generated 1 ultra high-quality sample with 60 inference steps")
|
||||
print(f"📊 Weather data points: {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")
|
||||
|
||||
print(f"\n💾 Saved files:")
|
||||
print(f" 📸 Ultra HQ prediction: ./predicted_plant_ultra_hq.jpg")
|
||||
print(f" 📊 Comparison image: ./predicted_plant_ultra_hq_comparison.jpg")
|
||||
|
||||
print(f"\n🏆 Ultra quality improvements:")
|
||||
print(f" ✅ 60 inference steps (maximum quality)")
|
||||
print(f" ✅ Higher guidance scales for perfect accuracy")
|
||||
print(f" ✅ Up to 1024x1024 resolution support")
|
||||
print(f" ✅ Single focused sample for consistency")
|
||||
print(f" ✅ Enhanced prompt engineering")
|
||||
print(f" ✅ Maximum quality JPEG compression (98%)")
|
||||
|
||||
else:
|
||||
print("Plant prediction failed.")
|
||||
print("❌ Ultra high-quality plant prediction failed.")
|
||||
print("💡 Check GPU memory and ensure RTX 3060 is available")
|
Loading…
Add table
Add a link
Reference in a new issue