|
import numpy as np |
|
import cv2 |
|
from segment_anything import sam_model_registry, SamPredictor |
|
import matplotlib.pyplot as plt |
|
from PIL import Image |
|
|
|
class SAMAnalyzer: |
|
def __init__(self, model_path="sam_vit_h_4b8939.pth"): |
|
"""Initialize SAM model for farmland segmentation""" |
|
self.model_path = model_path |
|
self.sam = None |
|
self.predictor = None |
|
try: |
|
print("Initializing SAM model...") |
|
self.sam = sam_model_registry["vit_h"](checkpoint=self.model_path) |
|
self.predictor = SamPredictor(self.sam) |
|
print("SAM model initialized successfully") |
|
except Exception as e: |
|
print(f"Error initializing SAM model: {e}") |
|
raise |
|
|
|
def process_image(self, image): |
|
"""Process uploaded image using SAM""" |
|
try: |
|
print("Starting image processing...") |
|
if image is None: |
|
raise ValueError("No image provided") |
|
|
|
|
|
if isinstance(image, np.ndarray): |
|
if len(image.shape) == 2: |
|
image = np.stack((image,)*3, axis=-1) |
|
elif len(image.shape) == 3 and image.shape[2] == 4: |
|
image = image[:,:,:3] |
|
|
|
if image.shape[2] == 3: |
|
image = cv2.cvtColor(cv2.cvtColor(image, cv2.COLOR_RGB2BGR), cv2.COLOR_BGR2RGB) |
|
else: |
|
raise ValueError("Invalid image format") |
|
|
|
print("Segmenting farmland...") |
|
farmland_mask = self.segment_farmland(image) |
|
|
|
print("Calculating vegetation index...") |
|
veg_index = self.calculate_vegetation_index(image, farmland_mask) |
|
|
|
print("Analyzing crop health...") |
|
health_analysis = self.analyze_crop_health(veg_index, farmland_mask) |
|
|
|
print("Creating visualization...") |
|
fig = self.create_visualization(image, farmland_mask, veg_index) |
|
|
|
return veg_index, health_analysis, fig |
|
|
|
except Exception as e: |
|
print(f"Error in image processing: {e}") |
|
return None, None, None |
|
|
|
def segment_farmland(self, image): |
|
"""Segment farmland using SAM2""" |
|
try: |
|
self.predictor.set_image(image) |
|
|
|
|
|
h, w = image.shape[:2] |
|
input_point = np.array([[w//2, h//2]]) |
|
input_label = np.array([1]) |
|
|
|
masks, scores, logits = self.predictor.predict( |
|
point_coords=input_point, |
|
point_labels=input_label, |
|
multimask_output=True |
|
) |
|
|
|
|
|
if len(masks) > 0: |
|
best_mask = masks[scores.argmax()] |
|
return best_mask |
|
else: |
|
raise ValueError("No valid masks generated") |
|
|
|
except Exception as e: |
|
print(f"Error in farmland segmentation: {e}") |
|
raise |
|
|
|
def calculate_vegetation_index(self, image, mask): |
|
"""Calculate vegetation index using RGB""" |
|
try: |
|
|
|
r, g, b = image[:,:,0], image[:,:,1], image[:,:,2] |
|
|
|
|
|
numerator = (2 * g.astype(float) - r.astype(float) - b.astype(float)) |
|
denominator = (2 * g.astype(float) + r.astype(float) + b.astype(float)) |
|
|
|
|
|
denominator[denominator == 0] = 1e-10 |
|
|
|
|
|
veg_index = numerator / denominator |
|
veg_index = (veg_index + 1) / 2 |
|
|
|
|
|
veg_index = veg_index * mask |
|
|
|
return veg_index |
|
|
|
except Exception as e: |
|
print(f"Error calculating vegetation index: {e}") |
|
raise |
|
|
|
def analyze_crop_health(self, veg_index, mask): |
|
"""Analyze crop health and insurance risk based on vegetation index""" |
|
try: |
|
valid_pixels = veg_index[mask > 0] |
|
if len(valid_pixels) == 0: |
|
return { |
|
'average_index': 0, |
|
'health_distribution': { |
|
'low_vegetation': 0, |
|
'moderate_vegetation': 0, |
|
'high_vegetation': 0 |
|
}, |
|
'overall_health': 'No vegetation detected', |
|
'farm_size': 0, |
|
'insurance_risk': 'Very High', |
|
'insurance_recommendations': 'Cannot assess insurance without vegetation data' |
|
} |
|
|
|
|
|
farm_size = np.sum(mask) * 0.0001 |
|
|
|
avg_index = np.mean(valid_pixels) |
|
health_categories = { |
|
'low_vegetation': np.sum((valid_pixels <= 0.3)) / len(valid_pixels), |
|
'moderate_vegetation': np.sum((valid_pixels > 0.3) & (valid_pixels <= 0.6)) / len(valid_pixels), |
|
'high_vegetation': np.sum((valid_pixels > 0.6)) / len(valid_pixels) |
|
} |
|
|
|
|
|
vegetation_uniformity = np.std(valid_pixels) |
|
|
|
|
|
insurance_risk = self.calculate_insurance_risk( |
|
avg_index, |
|
health_categories, |
|
vegetation_uniformity, |
|
farm_size |
|
) |
|
|
|
|
|
insurance_recommendations = self.get_insurance_recommendations( |
|
insurance_risk, |
|
health_categories, |
|
farm_size |
|
) |
|
|
|
return { |
|
'average_index': avg_index, |
|
'health_distribution': health_categories, |
|
'overall_health': 'Healthy' if avg_index > 0.5 else 'Needs attention', |
|
'farm_size': farm_size, |
|
'vegetation_uniformity': vegetation_uniformity, |
|
'insurance_risk': insurance_risk, |
|
'insurance_recommendations': insurance_recommendations |
|
} |
|
|
|
except Exception as e: |
|
print(f"Error analyzing crop health: {e}") |
|
raise |
|
|
|
def calculate_insurance_risk(self, avg_index, health_distribution, uniformity, farm_size): |
|
"""Calculate insurance risk level based on vegetation analysis""" |
|
risk_score = 0 |
|
|
|
|
|
if avg_index >= 0.6: |
|
risk_score += 40 |
|
elif avg_index >= 0.4: |
|
risk_score += 25 |
|
elif avg_index >= 0.2: |
|
risk_score += 10 |
|
|
|
|
|
if health_distribution['high_vegetation'] > 0.6: |
|
risk_score += 30 |
|
elif health_distribution['high_vegetation'] > 0.4: |
|
risk_score += 20 |
|
elif health_distribution['moderate_vegetation'] > 0.5: |
|
risk_score += 15 |
|
|
|
|
|
if uniformity < 0.1: |
|
risk_score += 20 |
|
elif uniformity < 0.2: |
|
risk_score += 15 |
|
elif uniformity < 0.3: |
|
risk_score += 10 |
|
|
|
|
|
if farm_size > 10: |
|
risk_score += 10 |
|
elif farm_size > 5: |
|
risk_score += 7 |
|
elif farm_size > 2: |
|
risk_score += 5 |
|
|
|
|
|
if risk_score >= 80: |
|
return "Low" |
|
elif risk_score >= 60: |
|
return "Moderate" |
|
elif risk_score >= 40: |
|
return "High" |
|
else: |
|
return "Very High" |
|
|
|
def get_insurance_recommendations(self, risk_level, health_distribution, farm_size): |
|
"""Get detailed insurance recommendations based on analysis""" |
|
base_recommendations = { |
|
"Low": { |
|
"policy_type": "Standard Coverage", |
|
"premium_level": "Lower premiums likely", |
|
"coverage_options": [ |
|
"β’ Basic crop insurance", |
|
"β’ Optional revenue protection", |
|
"β’ Minimal deductible options", |
|
"β’ Standard natural disaster coverage" |
|
], |
|
"additional_notes": "Farm shows good health indicators; standard coverage should be sufficient" |
|
}, |
|
"Moderate": { |
|
"policy_type": "Enhanced Coverage", |
|
"premium_level": "Moderate premiums", |
|
"coverage_options": [ |
|
"β’ Enhanced crop insurance", |
|
"β’ Revenue protection recommended", |
|
"β’ Weather index insurance", |
|
"β’ Moderate deductible options", |
|
"β’ Extended natural disaster coverage" |
|
], |
|
"additional_notes": "Consider additional coverage for specific risks" |
|
}, |
|
"High": { |
|
"policy_type": "Comprehensive Coverage", |
|
"premium_level": "Higher premiums likely", |
|
"coverage_options": [ |
|
"β’ Comprehensive crop insurance", |
|
"β’ Multi-peril crop insurance recommended", |
|
"β’ Weather index insurance strongly advised", |
|
"β’ Consider higher coverage limits", |
|
"β’ Full natural disaster coverage", |
|
"β’ Supplemental coverage option (SCO)" |
|
], |
|
"additional_notes": "Risk mitigation strategies should be implemented alongside insurance" |
|
}, |
|
"Very High": { |
|
"policy_type": "Maximum Coverage", |
|
"premium_level": "Significant premiums", |
|
"coverage_options": [ |
|
"β’ Maximum coverage crop insurance", |
|
"β’ Multi-peril crop insurance required", |
|
"β’ Weather index insurance essential", |
|
"β’ Additional risk management tools needed", |
|
"β’ Maximum natural disaster coverage", |
|
"β’ Enhanced coverage option (ECO)", |
|
"β’ Consider crop diversification insurance" |
|
], |
|
"additional_notes": "Immediate risk mitigation actions recommended before planting" |
|
} |
|
} |
|
|
|
|
|
size_category = "small" if farm_size < 5 else "medium" if farm_size < 10 else "large" |
|
|
|
recommendations = base_recommendations[risk_level] |
|
|
|
|
|
if size_category == "small": |
|
recommendations["coverage_options"].append("β’ Consider cooperative insurance options") |
|
recommendations["coverage_options"].append("β’ Micro-insurance options available") |
|
elif size_category == "medium": |
|
recommendations["coverage_options"].append("β’ Consider split coverage options") |
|
recommendations["coverage_options"].append("β’ Zone-based coverage recommended") |
|
else: |
|
recommendations["coverage_options"].append("β’ Consider zone-based coverage options") |
|
recommendations["coverage_options"].append("β’ Enterprise unit structure recommended") |
|
recommendations["coverage_options"].append("β’ Custom risk management solutions") |
|
|
|
return recommendations |
|
|
|
def create_visualization(self, image, mask, veg_index): |
|
"""Create visualization of results""" |
|
try: |
|
|
|
plt.close('all') |
|
|
|
|
|
fig = plt.figure(figsize=(15, 5)) |
|
|
|
|
|
plt.subplot(131) |
|
plt.imshow(image) |
|
plt.imshow(mask, alpha=0.3, cmap='gray') |
|
plt.title('Segmented Farmland') |
|
plt.axis('off') |
|
|
|
|
|
plt.subplot(132) |
|
im = plt.imshow(veg_index, cmap='RdYlGn', vmin=0, vmax=1) |
|
plt.colorbar(im, label='Vegetation Index') |
|
plt.title('Vegetation Index') |
|
plt.axis('off') |
|
|
|
|
|
plt.subplot(133) |
|
health_mask = np.zeros_like(veg_index) |
|
health_mask[veg_index <= 0.3] = 1 |
|
health_mask[(veg_index > 0.3) & (veg_index <= 0.6)] = 2 |
|
health_mask[veg_index > 0.6] = 3 |
|
health_mask = health_mask * mask |
|
|
|
im = plt.imshow(health_mask, cmap='viridis', vmin=1, vmax=3) |
|
cbar = plt.colorbar(im, ticks=[1, 2, 3]) |
|
cbar.set_label('Vegetation Levels') |
|
cbar.set_ticklabels(['Low', 'Moderate', 'High']) |
|
plt.title('Vegetation Levels') |
|
plt.axis('off') |
|
|
|
|
|
plt.tight_layout() |
|
|
|
return fig |
|
|
|
except Exception as e: |
|
print(f"Error creating visualization: {e}") |
|
raise |
|
|
|
def format_insurance_analysis(self, health_analysis): |
|
"""Format insurance analysis results as text""" |
|
try: |
|
farm_size = health_analysis['farm_size'] |
|
risk_level = health_analysis['insurance_risk'] |
|
recommendations = health_analysis['insurance_recommendations'] |
|
|
|
return f""" |
|
ποΈ Farm Analysis: |
|
β’ Approximate Size: {farm_size:.1f} hectares |
|
β’ Vegetation Uniformity: {health_analysis['vegetation_uniformity']:.2f} |
|
|
|
π― Insurance Risk Level: {risk_level} |
|
|
|
π‘ Recommended Insurance Strategy: |
|
β’ Policy Type: {recommendations['policy_type']} |
|
β’ Premium Level: {recommendations['premium_level']} |
|
|
|
π Recommended Coverage Options: |
|
{chr(10).join(recommendations['coverage_options'])} |
|
|
|
π Additional Notes: |
|
{recommendations['additional_notes']} |
|
""" |
|
except Exception as e: |
|
print(f"Error formatting insurance analysis: {e}") |
|
return "Error generating insurance recommendations" |