lyimo commited on
Commit
570d35a
·
verified ·
1 Parent(s): 64a2d44

Update part3.py

Browse files
Files changed (1) hide show
  1. part3.py +149 -118
part3.py CHANGED
@@ -7,14 +7,12 @@ from PIL import Image
7
 
8
  class SAMAnalyzer:
9
  def __init__(self, model_path="sam_vit_h_4b8939.pth"):
 
10
  self.model_path = model_path
11
  self.sam = None
12
  self.predictor = None
13
- self.initialize_sam()
14
-
15
- def initialize_sam(self):
16
- """Initialize SAM model"""
17
  try:
 
18
  self.sam = sam_model_registry["vit_h"](checkpoint=self.model_path)
19
  self.predictor = SamPredictor(self.sam)
20
  print("SAM model initialized successfully")
@@ -22,158 +20,191 @@ class SAMAnalyzer:
22
  print(f"Error initializing SAM model: {e}")
23
  raise
24
 
25
- def process_image(self, image_data):
26
  """Process uploaded image using SAM"""
27
  try:
28
- # Convert uploaded image to numpy array
29
- if isinstance(image_data, (str, bytes)):
30
- if isinstance(image_data, str):
31
- image = cv2.imread(image_data)
32
- else:
33
- nparr = np.frombuffer(image_data, np.uint8)
34
- image = cv2.imdecode(nparr, cv2.IMREAD_COLOR)
35
- image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
 
 
36
  else:
37
- image = np.array(Image.open(image_data))
38
 
39
- # Segment farmland
40
  print("Segmenting farmland...")
41
  farmland_mask = self.segment_farmland(image)
42
 
43
- # Calculate vegetation index
44
  print("Calculating vegetation index...")
45
  veg_index = self.calculate_vegetation_index(image, farmland_mask)
46
 
47
- # Analyze health
48
  print("Analyzing crop health...")
49
  health_analysis = self.analyze_crop_health(veg_index, farmland_mask)
50
 
51
- # Create visualization
52
- print("Generating visualization...")
53
  viz_plot = self.create_visualization(image, farmland_mask, veg_index)
54
 
55
  return veg_index, health_analysis, viz_plot
56
 
57
  except Exception as e:
58
- print(f"Error processing image: {e}")
59
  return None, None, None
60
 
61
  def segment_farmland(self, image):
62
  """Segment farmland using SAM2"""
63
- self.predictor.set_image(image)
64
-
65
- # Generate automatic mask proposals
66
- h, w = image.shape[:2]
67
- input_point = np.array([[w//2, h//2]])
68
- input_label = np.array([1])
69
-
70
- masks, scores, logits = self.predictor.predict(
71
- point_coords=input_point,
72
- point_labels=input_label,
73
- multimask_output=True
74
- )
 
 
 
 
 
75
 
76
- # Select best mask
77
- best_mask = masks[scores.argmax()]
78
- return best_mask
79
 
80
  def calculate_vegetation_index(self, image, mask):
81
  """Calculate vegetation index using RGB"""
82
- r, g, b = image[:,:,0], image[:,:,1], image[:,:,2]
 
 
 
 
 
 
 
 
 
83
 
84
- numerator = (2 * g.astype(float) - r.astype(float) - b.astype(float))
85
- denominator = (2 * g.astype(float) + r.astype(float) + b.astype(float))
86
- denominator[denominator == 0] = 1e-10
 
 
 
87
 
88
- veg_index = numerator / denominator
89
- veg_index = (veg_index + 1) / 2
90
- veg_index = veg_index * mask
91
 
92
- return veg_index
 
 
93
 
94
  def analyze_crop_health(self, veg_index, mask):
95
  """Analyze crop health based on vegetation index"""
96
- valid_pixels = veg_index[mask > 0]
97
- if len(valid_pixels) == 0:
98
- return {
99
- 'average_index': 0,
100
- 'health_distribution': {
101
- 'low_vegetation': 0,
102
- 'moderate_vegetation': 0,
103
- 'high_vegetation': 0
104
- },
105
- 'overall_health': 'No vegetation detected'
 
 
 
 
 
 
 
 
106
  }
107
 
108
- avg_index = np.mean(valid_pixels)
109
- health_categories = {
110
- 'low_vegetation': np.sum((valid_pixels <= 0.3)) / len(valid_pixels),
111
- 'moderate_vegetation': np.sum((valid_pixels > 0.3) & (valid_pixels <= 0.6)) / len(valid_pixels),
112
- 'high_vegetation': np.sum((valid_pixels > 0.6)) / len(valid_pixels)
113
- }
114
 
115
- return {
116
- 'average_index': avg_index,
117
- 'health_distribution': health_categories,
118
- 'overall_health': 'Healthy' if avg_index > 0.5 else 'Needs attention'
119
- }
 
 
 
 
120
 
121
  def create_visualization(self, image, mask, veg_index):
122
  """Create visualization of results"""
123
- fig = plt.figure(figsize=(15, 5))
124
-
125
- # Original image with mask overlay
126
- plt.subplot(131)
127
- plt.imshow(image)
128
- plt.imshow(mask, alpha=0.3, cmap='gray')
129
- plt.title('Segmented Farmland')
130
- plt.axis('off')
131
-
132
- # Vegetation index heatmap
133
- plt.subplot(132)
134
- plt.imshow(veg_index, cmap='RdYlGn')
135
- plt.colorbar(label='Vegetation Index')
136
- plt.title('Vegetation Index')
137
- plt.axis('off')
138
-
139
- # Health classification
140
- plt.subplot(133)
141
- health_mask = np.zeros_like(veg_index)
142
- health_mask[veg_index <= 0.3] = 1
143
- health_mask[(veg_index > 0.3) & (veg_index <= 0.6)] = 2
144
- health_mask[veg_index > 0.6] = 3
145
- health_mask = health_mask * mask
146
- plt.imshow(health_mask, cmap='viridis')
147
- plt.colorbar(ticks=[1, 2, 3],
148
- label='Vegetation Levels',
149
- boundaries=np.arange(0.5, 4.5),
150
- values=[1, 2, 3])
151
- plt.title('Vegetation Levels')
152
- plt.axis('off')
153
-
154
- plt.tight_layout()
155
-
156
- # Save plot to buffer
157
- buf = io.BytesIO()
158
- plt.savefig(buf, format='png', bbox_inches='tight')
159
- buf.seek(0)
160
- plt.close()
161
-
162
- return buf
 
 
 
 
 
 
 
163
 
164
  def format_analysis_text(self, health_analysis):
165
  """Format health analysis results as text"""
166
- return f"""
167
- 🌿 Vegetation Analysis Results:
168
-
169
- 📊 Average Vegetation Index: {health_analysis['average_index']:.2f}
170
-
171
- 🌱 Vegetation Distribution:
172
- • Low Vegetation: {health_analysis['health_distribution']['low_vegetation']*100:.1f}%
173
- • Moderate Vegetation: {health_analysis['health_distribution']['moderate_vegetation']*100:.1f}%
174
- • High Vegetation: {health_analysis['health_distribution']['high_vegetation']*100:.1f}%
175
-
176
- 📋 Overall Health Status: {health_analysis['overall_health']}
177
-
178
- Note: Analysis uses SAM2 for farmland segmentation
179
- """
 
 
 
 
 
7
 
8
  class SAMAnalyzer:
9
  def __init__(self, model_path="sam_vit_h_4b8939.pth"):
10
+ """Initialize SAM model for farmland segmentation"""
11
  self.model_path = model_path
12
  self.sam = None
13
  self.predictor = None
 
 
 
 
14
  try:
15
+ print("Initializing SAM model...")
16
  self.sam = sam_model_registry["vit_h"](checkpoint=self.model_path)
17
  self.predictor = SamPredictor(self.sam)
18
  print("SAM model initialized successfully")
 
20
  print(f"Error initializing SAM model: {e}")
21
  raise
22
 
23
+ def process_image(self, image):
24
  """Process uploaded image using SAM"""
25
  try:
26
+ print("Starting image processing...")
27
+ if image is None:
28
+ raise ValueError("No image provided")
29
+
30
+ # Ensure image is in correct format
31
+ if isinstance(image, np.ndarray):
32
+ if len(image.shape) == 2: # Grayscale
33
+ image = np.stack((image,)*3, axis=-1)
34
+ elif len(image.shape) == 3 and image.shape[2] == 4: # RGBA
35
+ image = image[:,:,:3]
36
  else:
37
+ raise ValueError("Invalid image format")
38
 
 
39
  print("Segmenting farmland...")
40
  farmland_mask = self.segment_farmland(image)
41
 
 
42
  print("Calculating vegetation index...")
43
  veg_index = self.calculate_vegetation_index(image, farmland_mask)
44
 
 
45
  print("Analyzing crop health...")
46
  health_analysis = self.analyze_crop_health(veg_index, farmland_mask)
47
 
48
+ print("Creating visualization...")
 
49
  viz_plot = self.create_visualization(image, farmland_mask, veg_index)
50
 
51
  return veg_index, health_analysis, viz_plot
52
 
53
  except Exception as e:
54
+ print(f"Error in image processing: {e}")
55
  return None, None, None
56
 
57
  def segment_farmland(self, image):
58
  """Segment farmland using SAM2"""
59
+ try:
60
+ self.predictor.set_image(image)
61
+
62
+ # Generate automatic mask proposals
63
+ h, w = image.shape[:2]
64
+ input_point = np.array([[w//2, h//2]]) # Center point
65
+ input_label = np.array([1]) # Foreground
66
+
67
+ masks, scores, logits = self.predictor.predict(
68
+ point_coords=input_point,
69
+ point_labels=input_label,
70
+ multimask_output=True
71
+ )
72
+
73
+ # Select best mask
74
+ best_mask = masks[scores.argmax()]
75
+ return best_mask
76
 
77
+ except Exception as e:
78
+ print(f"Error in farmland segmentation: {e}")
79
+ raise
80
 
81
  def calculate_vegetation_index(self, image, mask):
82
  """Calculate vegetation index using RGB"""
83
+ try:
84
+ # Extract RGB channels
85
+ r, g, b = image[:,:,0], image[:,:,1], image[:,:,2]
86
+
87
+ # Calculate visible-band vegetation index
88
+ numerator = (2 * g.astype(float) - r.astype(float) - b.astype(float))
89
+ denominator = (2 * g.astype(float) + r.astype(float) + b.astype(float))
90
+
91
+ # Avoid division by zero
92
+ denominator[denominator == 0] = 1e-10
93
 
94
+ # Calculate index and normalize
95
+ veg_index = numerator / denominator
96
+ veg_index = (veg_index + 1) / 2 # Normalize to 0-1 range
97
+
98
+ # Apply mask
99
+ veg_index = veg_index * mask
100
 
101
+ return veg_index
 
 
102
 
103
+ except Exception as e:
104
+ print(f"Error calculating vegetation index: {e}")
105
+ raise
106
 
107
  def analyze_crop_health(self, veg_index, mask):
108
  """Analyze crop health based on vegetation index"""
109
+ try:
110
+ valid_pixels = veg_index[mask > 0]
111
+ if len(valid_pixels) == 0:
112
+ return {
113
+ 'average_index': 0,
114
+ 'health_distribution': {
115
+ 'low_vegetation': 0,
116
+ 'moderate_vegetation': 0,
117
+ 'high_vegetation': 0
118
+ },
119
+ 'overall_health': 'No vegetation detected'
120
+ }
121
+
122
+ avg_index = np.mean(valid_pixels)
123
+ health_categories = {
124
+ 'low_vegetation': np.sum((valid_pixels <= 0.3)) / len(valid_pixels),
125
+ 'moderate_vegetation': np.sum((valid_pixels > 0.3) & (valid_pixels <= 0.6)) / len(valid_pixels),
126
+ 'high_vegetation': np.sum((valid_pixels > 0.6)) / len(valid_pixels)
127
  }
128
 
129
+ overall_health = 'Healthy' if avg_index > 0.5 else 'Needs attention'
 
 
 
 
 
130
 
131
+ return {
132
+ 'average_index': avg_index,
133
+ 'health_distribution': health_categories,
134
+ 'overall_health': overall_health
135
+ }
136
+
137
+ except Exception as e:
138
+ print(f"Error analyzing crop health: {e}")
139
+ raise
140
 
141
  def create_visualization(self, image, mask, veg_index):
142
  """Create visualization of results"""
143
+ try:
144
+ fig = plt.figure(figsize=(15, 5))
145
+
146
+ # Original image with mask overlay
147
+ plt.subplot(131)
148
+ plt.imshow(image)
149
+ plt.imshow(mask, alpha=0.3, cmap='gray')
150
+ plt.title('Segmented Farmland')
151
+ plt.axis('off')
152
+
153
+ # Vegetation index heatmap
154
+ plt.subplot(132)
155
+ plt.imshow(veg_index, cmap='RdYlGn')
156
+ plt.colorbar(label='Vegetation Index')
157
+ plt.title('Vegetation Index')
158
+ plt.axis('off')
159
+
160
+ # Health classification
161
+ plt.subplot(133)
162
+ health_mask = np.zeros_like(veg_index)
163
+ health_mask[veg_index <= 0.3] = 1 # Low
164
+ health_mask[(veg_index > 0.3) & (veg_index <= 0.6)] = 2 # Moderate
165
+ health_mask[veg_index > 0.6] = 3 # High
166
+ health_mask = health_mask * mask
167
+ plt.imshow(health_mask, cmap='viridis')
168
+ plt.colorbar(
169
+ ticks=[1, 2, 3],
170
+ label='Vegetation Levels',
171
+ boundaries=np.arange(0.5, 4.5),
172
+ values=[1, 2, 3]
173
+ )
174
+ plt.title('Vegetation Levels')
175
+ plt.axis('off')
176
+
177
+ plt.tight_layout()
178
+
179
+ # Save plot to buffer
180
+ buf = io.BytesIO()
181
+ plt.savefig(buf, format='png', bbox_inches='tight', dpi=300)
182
+ buf.seek(0)
183
+ plt.close()
184
+
185
+ return buf
186
+
187
+ except Exception as e:
188
+ print(f"Error creating visualization: {e}")
189
+ raise
190
 
191
  def format_analysis_text(self, health_analysis):
192
  """Format health analysis results as text"""
193
+ try:
194
+ return f"""
195
+ 🌿 Vegetation Analysis Results:
196
+
197
+ 📊 Average Vegetation Index: {health_analysis['average_index']:.2f}
198
+
199
+ 🌱 Vegetation Distribution:
200
+ • Low Vegetation: {health_analysis['health_distribution']['low_vegetation']*100:.1f}%
201
+ • Moderate Vegetation: {health_analysis['health_distribution']['moderate_vegetation']*100:.1f}%
202
+ • High Vegetation: {health_analysis['health_distribution']['high_vegetation']*100:.1f}%
203
+
204
+ 📋 Overall Health Status: {health_analysis['overall_health']}
205
+
206
+ Note: Analysis uses SAM2 for farmland segmentation
207
+ """
208
+ except Exception as e:
209
+ print(f"Error formatting analysis text: {e}")
210
+ return "Error generating analysis report"