Ayushman2802 commited on
Commit
fe89f67
·
verified ·
1 Parent(s): 7ce53fa

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +114 -72
app.py CHANGED
@@ -5,6 +5,7 @@ from PIL import Image
5
  from transformers import AutoProcessor, AutoModelForVision2Seq
6
  import cv2
7
  from huggingface_hub import hf_hub_download
 
8
  from segment_anything import SamPredictor, sam_model_registry
9
 
10
  # India-specific constants
@@ -18,60 +19,83 @@ ANNUAL_MAINTENANCE_COST_PERCENT = 0.01 # 1% of installation cost
18
  LIFESPAN_YEARS = 25 # typical solar panel lifespan
19
 
20
  def load_models():
21
- print("Loading models...")
22
- device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
23
-
24
- # Load LLaVA model (float16 on GPU if available)
25
- processor = AutoProcessor.from_pretrained("llava-hf/llava-1.5-7b-hf")
26
- model = AutoModelForVision2Seq.from_pretrained(
27
- "llava-hf/llava-1.5-7b-hf",
28
- torch_dtype=torch.float16 if device.type=="cuda" else torch.float32
29
- )
30
- model.to(device)
31
-
32
- # Download SAM checkpoint from your HF repo at runtime
33
- repo_id = "kunkaran/sam_vit_h_4b8939.pth" # Replace with your actual repo if different
34
- filename = "sam_vit_h_4b8939.pth" # Filename in that repo
35
- print(f"Downloading checkpoint {filename} from repo {repo_id} ...")
36
- sam_checkpoint_path = hf_hub_download(repo_id=repo_id, filename=filename)
37
- print(f"Checkpoint downloaded to {sam_checkpoint_path}")
38
-
39
- # Load SAM model
40
- sam = sam_model_registry["vit_h"](checkpoint=sam_checkpoint_path)
41
- sam.to(device)
42
- sam_predictor = SamPredictor(sam)
43
-
44
- print("Models loaded.")
45
- return processor, model, sam_predictor, device
 
 
 
 
 
 
 
 
 
 
 
 
 
 
46
 
47
  def segment_rooftop(image, sam_predictor):
48
- if isinstance(image, Image.Image):
49
- image_array = np.array(image)
50
- else:
51
- image_array = image
52
-
53
- sam_predictor.set_image(image_array)
54
- h, w = image_array.shape[:2]
55
- input_point = np.array([[w//2, h//2]])
56
- input_label = np.array([1])
57
-
58
- masks, _, _ = sam_predictor.predict(
59
- point_coords=input_point,
60
- point_labels=input_label,
61
- multimask_output=True
62
- )
63
- best_mask = masks[0] # Choose first mask
64
- return best_mask
 
 
 
 
 
 
 
 
 
65
 
66
  def calculate_area(mask, image_width_meters=10.0):
67
  pixel_area = np.sum(mask)
68
  total_pixels = mask.shape[0] * mask.shape[1]
69
  image_area_m2 = image_width_meters * image_width_meters # Approximate
70
  rooftop_area_m2 = (pixel_area / total_pixels) * image_area_m2
71
- return rooftop_area_m2
72
 
73
  def calculate_roi(area_m2):
74
- num_panels = int(area_m2 / PANEL_SIZE * 0.8)
75
  total_capacity_kw = num_panels * PANEL_CAPACITY
76
  daily_production_kwh = total_capacity_kw * SOLAR_IRRADIATION_INDIA * SOLAR_PANEL_EFFICIENCY
77
  annual_production_kwh = daily_production_kwh * 365
@@ -94,32 +118,43 @@ def calculate_roi(area_m2):
94
  }
95
 
96
  def analyze_rooftop(image, processor, model, sam_predictor, device):
97
- mask = segment_rooftop(image, sam_predictor)
98
- area_m2 = calculate_area(mask)
99
- roi_data = calculate_roi(area_m2)
100
-
101
- prompt = (
102
- "Analyze this rooftop image for solar panel installation. "
103
- "Comment on orientation, obstructions, and ideal panel placement."
104
- )
105
-
106
- if not isinstance(image, Image.Image):
107
- image = Image.fromarray(image)
108
-
109
- inputs = processor(text=prompt, images=image, return_tensors="pt").to(device)
110
- output = model.generate(**inputs, max_new_tokens=300)
111
- llava_analysis = processor.decode(output[0], skip_special_tokens=True)
112
-
113
- image_array = np.array(image)
114
- visualization = image_array.copy()
115
- mask_overlay = np.zeros_like(visualization)
116
- if visualization.ndim == 2: # grayscale image
117
- visualization = cv2.cvtColor(visualization, cv2.COLOR_GRAY2RGB)
118
- mask_overlay[:,:,0] = (mask * 255).astype(np.uint8)
119
- visualization = cv2.addWeighted(visualization.astype(np.uint8), 0.7, mask_overlay, 0.3, 0)
120
- visualization = Image.fromarray(visualization)
121
-
122
- results_str = f"""
 
 
 
 
 
 
 
 
 
 
 
123
  ## Rooftop Analysis Results
124
  ### Technical Assessment
125
  - Usable Rooftop Area: {roi_data['rooftop_area_m2']} m²
@@ -135,8 +170,13 @@ def analyze_rooftop(image, processor, model, sam_predictor, device):
135
  {llava_analysis}
136
  """
137
 
138
- return visualization, results_str
 
 
 
 
139
 
 
140
  # Load models once (synchronously)
141
  processor, model, sam_predictor, device = load_models()
142
 
@@ -150,7 +190,9 @@ demo = gr.Interface(
150
  ],
151
  title="🔆 Solar Rooftop Analyzer - India Edition",
152
  description="Upload a satellite image of a rooftop to get detailed solar potential analysis with India-specific ROI calculations.",
 
153
  )
154
 
155
  if __name__ == "__main__":
156
- demo.launch()
 
 
5
  from transformers import AutoProcessor, AutoModelForVision2Seq
6
  import cv2
7
  from huggingface_hub import hf_hub_download
8
+ import os
9
  from segment_anything import SamPredictor, sam_model_registry
10
 
11
  # India-specific constants
 
19
  LIFESPAN_YEARS = 25 # typical solar panel lifespan
20
 
21
  def load_models():
22
+ try:
23
+ print("Loading models...")
24
+ device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
25
+ print(f"Using device: {device}")
26
+
27
+ # Load LLaVA model (float16 on GPU if available)
28
+ processor = AutoProcessor.from_pretrained("llava-hf/llava-1.5-7b-hf")
29
+ model = AutoModelForVision2Seq.from_pretrained(
30
+ "llava-hf/llava-1.5-7b-hf",
31
+ torch_dtype=torch.float16 if device.type=="cuda" else torch.float32
32
+ )
33
+ model.to(device)
34
+ print("LLaVA model loaded successfully")
35
+
36
+ # Download SAM checkpoint from your HF repo at runtime
37
+ repo_id = "kunkaran/sam_vit_h_4b8939.pth" # Replace with your actual repo if different
38
+ filename = "sam_vit_h_4b8939.pth" # Filename in that repo
39
+
40
+ # Check if file already exists locally to avoid redundant downloads
41
+ local_path = os.path.join(os.getcwd(), filename)
42
+ if os.path.exists(local_path):
43
+ sam_checkpoint_path = local_path
44
+ print(f"Using existing checkpoint at {sam_checkpoint_path}")
45
+ else:
46
+ print(f"Downloading checkpoint {filename} from repo {repo_id} ...")
47
+ sam_checkpoint_path = hf_hub_download(repo_id=repo_id, filename=filename)
48
+ print(f"Checkpoint downloaded to {sam_checkpoint_path}")
49
+
50
+ # Load SAM model
51
+ sam = sam_model_registry["vit_h"](checkpoint=sam_checkpoint_path)
52
+ sam.to(device)
53
+ sam_predictor = SamPredictor(sam)
54
+ print("SAM model loaded successfully")
55
+
56
+ return processor, model, sam_predictor, device
57
+
58
+ except Exception as e:
59
+ print(f"Error loading models: {str(e)}")
60
+ raise
61
 
62
  def segment_rooftop(image, sam_predictor):
63
+ try:
64
+ if isinstance(image, Image.Image):
65
+ image_array = np.array(image)
66
+ else:
67
+ image_array = image
68
+
69
+ # Ensure image is RGB if it's grayscale
70
+ if len(image_array.shape) == 2 or (len(image_array.shape) == 3 and image_array.shape[2] == 1):
71
+ image_array = cv2.cvtColor(image_array, cv2.COLOR_GRAY2RGB)
72
+
73
+ sam_predictor.set_image(image_array)
74
+ h, w = image_array.shape[:2]
75
+ input_point = np.array([[w//2, h//2]])
76
+ input_label = np.array([1])
77
+
78
+ masks, _, _ = sam_predictor.predict(
79
+ point_coords=input_point,
80
+ point_labels=input_label,
81
+ multimask_output=True
82
+ )
83
+ best_mask = masks[0] # Choose first mask
84
+ return best_mask
85
+ except Exception as e:
86
+ print(f"Error in segmentation: {str(e)}")
87
+ # Return a blank mask as fallback
88
+ return np.zeros((image_array.shape[0], image_array.shape[1]), dtype=bool)
89
 
90
  def calculate_area(mask, image_width_meters=10.0):
91
  pixel_area = np.sum(mask)
92
  total_pixels = mask.shape[0] * mask.shape[1]
93
  image_area_m2 = image_width_meters * image_width_meters # Approximate
94
  rooftop_area_m2 = (pixel_area / total_pixels) * image_area_m2
95
+ return max(0.1, rooftop_area_m2) # Ensure we don't return zero area
96
 
97
  def calculate_roi(area_m2):
98
+ num_panels = max(1, int(area_m2 / PANEL_SIZE * 0.8))
99
  total_capacity_kw = num_panels * PANEL_CAPACITY
100
  daily_production_kwh = total_capacity_kw * SOLAR_IRRADIATION_INDIA * SOLAR_PANEL_EFFICIENCY
101
  annual_production_kwh = daily_production_kwh * 365
 
118
  }
119
 
120
  def analyze_rooftop(image, processor, model, sam_predictor, device):
121
+ try:
122
+ mask = segment_rooftop(image, sam_predictor)
123
+ area_m2 = calculate_area(mask)
124
+ roi_data = calculate_roi(area_m2)
125
+
126
+ prompt = (
127
+ "As a solar engineering expert in India, analyze this rooftop for solar installation potential. "
128
+ "Consider: 1) Roof orientation and tilt for optimal sun exposure in Indian latitudes, "
129
+ "2) Potential obstructions like chimneys, water tanks, or shadows from nearby structures, "
130
+ "3) Structural integrity and recommended panel layout for monsoon resistance, "
131
+ "4) Regional factors like dust accumulation and temperature impact on efficiency, "
132
+ "5) Space utilization for maximizing energy generation with Indian solar irradiation patterns. "
133
+ "Provide a detailed assessment for this specific rooftop."
134
+ )
135
+
136
+ if not isinstance(image, Image.Image):
137
+ image = Image.fromarray(image)
138
+
139
+ inputs = processor(text=prompt, images=image, return_tensors="pt").to(device)
140
+ output = model.generate(**inputs, max_new_tokens=300)
141
+ llava_analysis = processor.decode(output[0], skip_special_tokens=True)
142
+
143
+ image_array = np.array(image)
144
+ visualization = image_array.copy()
145
+
146
+ # Ensure visualization array is RGB
147
+ if visualization.ndim == 2: # grayscale image
148
+ visualization = cv2.cvtColor(visualization, cv2.COLOR_GRAY2RGB)
149
+ elif visualization.shape[2] == 4: # RGBA image
150
+ visualization = visualization[:,:,:3]
151
+
152
+ mask_overlay = np.zeros_like(visualization)
153
+ mask_overlay[:,:,0] = (mask * 255).astype(np.uint8)
154
+ visualization = cv2.addWeighted(visualization.astype(np.uint8), 0.7, mask_overlay, 0.3, 0)
155
+ visualization = Image.fromarray(visualization)
156
+
157
+ results_str = f"""
158
  ## Rooftop Analysis Results
159
  ### Technical Assessment
160
  - Usable Rooftop Area: {roi_data['rooftop_area_m2']} m²
 
170
  {llava_analysis}
171
  """
172
 
173
+ return visualization, results_str
174
+ except Exception as e:
175
+ error_message = f"Error during analysis: {str(e)}"
176
+ print(error_message)
177
+ return Image.fromarray(np.zeros((400, 400, 3), dtype=np.uint8)), f"## Error\n{error_message}"
178
 
179
+ print("Initializing application...")
180
  # Load models once (synchronously)
181
  processor, model, sam_predictor, device = load_models()
182
 
 
190
  ],
191
  title="🔆 Solar Rooftop Analyzer - India Edition",
192
  description="Upload a satellite image of a rooftop to get detailed solar potential analysis with India-specific ROI calculations.",
193
+ examples=["sample1.jpg", "sample2.jpg"] if os.path.exists("sample1.jpg") else None
194
  )
195
 
196
  if __name__ == "__main__":
197
+ print("Starting Gradio server...")
198
+ demo.launch()