Spaces:
Runtime error
Runtime error
Harsh-7300
commited on
Create app.py
Browse files
app.py
ADDED
@@ -0,0 +1,152 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import cv2
|
2 |
+
import numpy as np
|
3 |
+
import pandas as pd
|
4 |
+
import gradio as gr
|
5 |
+
from keras.models import load_model
|
6 |
+
from sklearn.preprocessing import OneHotEncoder, StandardScaler
|
7 |
+
|
8 |
+
# Load the pre-trained model
|
9 |
+
loaded_model = load_model('solar_irradiance_model.keras')
|
10 |
+
|
11 |
+
# Load the dataset for encoder and scaler setup
|
12 |
+
data = pd.read_csv('Solar_Irradiance.csv')
|
13 |
+
data['Latitude'] = data['Latitude'].str.rstrip('°').astype(float)
|
14 |
+
data['Longitude'] = data['Longitude'].str.rstrip('°').astype(float)
|
15 |
+
|
16 |
+
# Features and encoder/scaler setup
|
17 |
+
features = data[['Month', 'Hour', 'Latitude', 'Longitude', 'Panel_Capacity(W)', 'Panel_Efficiency', 'Wind_Speed(km/h)', 'Cloud_Cover(%)', 'temperature (°f)']]
|
18 |
+
encoder = OneHotEncoder(sparse_output=False, categories='auto')
|
19 |
+
categorical_features = features[['Month', 'Hour']]
|
20 |
+
encoder.fit(categorical_features)
|
21 |
+
scaler = StandardScaler()
|
22 |
+
numerical_features = features[['Latitude', 'Longitude', 'Panel_Capacity(W)', 'Panel_Efficiency', 'Wind_Speed(km/h)', 'Cloud_Cover(%)', 'temperature (°f)']]
|
23 |
+
scaler.fit(numerical_features)
|
24 |
+
|
25 |
+
# Shadow Removal Function
|
26 |
+
def remove_shadows(image):
|
27 |
+
"""Removes shadows using illumination normalization."""
|
28 |
+
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
|
29 |
+
blurred = cv2.GaussianBlur(gray, (21, 21), 0)
|
30 |
+
normalized = cv2.divide(gray, blurred, scale=255)
|
31 |
+
result = cv2.cvtColor(normalized, cv2.COLOR_GRAY2BGR)
|
32 |
+
return result
|
33 |
+
|
34 |
+
# Preprocess Image with Watershed Algorithm
|
35 |
+
def apply_watershed(image):
|
36 |
+
# Step 1: Remove shadows
|
37 |
+
shadow_free_image = remove_shadows(image)
|
38 |
+
|
39 |
+
# Step 2: Denoise the shadow-free image
|
40 |
+
denoised = cv2.fastNlMeansDenoisingColored(shadow_free_image, None, 10, 10, 7, 21)
|
41 |
+
gray = cv2.cvtColor(denoised, cv2.COLOR_BGR2GRAY)
|
42 |
+
|
43 |
+
# Step 3: Thresholding
|
44 |
+
_, binary = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
|
45 |
+
|
46 |
+
# Step 4: Morphological operations to get foreground and background
|
47 |
+
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5))
|
48 |
+
sure_bg = cv2.dilate(binary, kernel, iterations=3)
|
49 |
+
sure_fg = cv2.erode(binary, kernel, iterations=3)
|
50 |
+
unknown = cv2.subtract(sure_bg, sure_fg)
|
51 |
+
|
52 |
+
# Step 5: Marker labelling
|
53 |
+
_, markers = cv2.connectedComponents(sure_fg)
|
54 |
+
markers = markers + 1
|
55 |
+
markers[unknown == 255] = 0
|
56 |
+
|
57 |
+
# Step 6: Apply Watershed
|
58 |
+
markers = cv2.watershed(image, markers)
|
59 |
+
segmented = np.zeros_like(image)
|
60 |
+
segmented[markers > 1] = image[markers > 1]
|
61 |
+
|
62 |
+
return segmented, markers
|
63 |
+
|
64 |
+
# Calculate Usable Roof Area
|
65 |
+
# Calculate Usable Roof Area
|
66 |
+
def find_usable_area(image, min_area, panel_area):
|
67 |
+
segmented_image, markers = apply_watershed(image)
|
68 |
+
gray = cv2.cvtColor(segmented_image, cv2.COLOR_BGR2GRAY)
|
69 |
+
contours, _ = cv2.findContours(gray, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
|
70 |
+
|
71 |
+
usable_area = 0
|
72 |
+
output_image = image.copy()
|
73 |
+
|
74 |
+
for contour in contours:
|
75 |
+
area = cv2.contourArea(contour)
|
76 |
+
if area >= min_area:
|
77 |
+
usable_area += area
|
78 |
+
# Mark usable area in green
|
79 |
+
cv2.drawContours(output_image, [contour], -1, (0, 255, 0), 3)
|
80 |
+
else:
|
81 |
+
# Mark unusable area in red
|
82 |
+
cv2.drawContours(output_image, [contour], -1, (0, 0, 255), 3)
|
83 |
+
|
84 |
+
num_panels = usable_area // panel_area # Number of panels that fit in the usable area
|
85 |
+
return usable_area, int(num_panels), output_image
|
86 |
+
|
87 |
+
|
88 |
+
# Predict Irradiance
|
89 |
+
def predict_irradiance(month, hour, latitude, longitude, panel_capacity, panel_efficiency, wind_speed, cloud_cover, temperature):
|
90 |
+
encoded_month_hour = encoder.transform([[month, hour]])
|
91 |
+
scaled_features = scaler.transform([[latitude, longitude, panel_capacity, panel_efficiency, wind_speed, cloud_cover, temperature]])
|
92 |
+
processed_features = np.concatenate((encoded_month_hour, scaled_features), axis=1)
|
93 |
+
reshaped_features = np.reshape(processed_features, (1, 1, processed_features.shape[1]))
|
94 |
+
predicted_irradiance = loaded_model.predict(reshaped_features)
|
95 |
+
return max(predicted_irradiance[0][0], 0.0)
|
96 |
+
|
97 |
+
# Main Function
|
98 |
+
def calculate_solar_energy(image, month, hour, latitude, longitude, panel_capacity, panel_efficiency, wind_speed, cloud_cover, temperature):
|
99 |
+
panel_area = 7 # m² per panel
|
100 |
+
min_area = 1000 # Minimum contour area to consider for valid roof
|
101 |
+
|
102 |
+
# Step 1: Find usable roof area from segmented image
|
103 |
+
usable_area, num_panels, segmented_image = find_usable_area(image, min_area, panel_area)
|
104 |
+
if usable_area == 0:
|
105 |
+
return "No valid roof detected.", segmented_image
|
106 |
+
|
107 |
+
# Step 2: Predict irradiance for the given environmental conditions
|
108 |
+
irradiance = predict_irradiance(month, hour, latitude, longitude, panel_capacity, panel_efficiency, wind_speed, cloud_cover, temperature)
|
109 |
+
|
110 |
+
# Step 3: Calculate potential energy and cost based on panels and irradiance
|
111 |
+
potential_energy = num_panels * panel_area * irradiance * panel_efficiency # in Watts
|
112 |
+
potential_energy_kwh = potential_energy / 1000 # Convert to kWh
|
113 |
+
cost_per_panel = 1000 # Rs. per panel
|
114 |
+
total_cost = num_panels * cost_per_panel
|
115 |
+
|
116 |
+
results = (f"Usable Roof Area: {usable_area:.2f} m²\n"
|
117 |
+
f"Number of Panels: {num_panels}\n"
|
118 |
+
f"Predicted Irradiance: {irradiance:.2f} W/m²\n"
|
119 |
+
f"Potential Solar Energy: {potential_energy_kwh:.2f} kWh\n"
|
120 |
+
f"Total Cost of Panels: Rs. {total_cost}")
|
121 |
+
|
122 |
+
return results, segmented_image
|
123 |
+
|
124 |
+
# Gradio Interface function
|
125 |
+
def interface_fn(image, month, hour, latitude, longitude, panel_capacity, panel_efficiency, wind_speed, cloud_cover, temperature):
|
126 |
+
results, segmented_image = calculate_solar_energy(image, month, hour, latitude, longitude, panel_capacity, panel_efficiency, wind_speed, cloud_cover, temperature)
|
127 |
+
return results, segmented_image
|
128 |
+
|
129 |
+
# Gradio interface setup
|
130 |
+
interface = gr.Interface(
|
131 |
+
fn=interface_fn,
|
132 |
+
inputs=[
|
133 |
+
gr.Image(type="numpy", label="Upload Rooftop Image"),
|
134 |
+
gr.Dropdown(['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'], label="Month"),
|
135 |
+
gr.Slider(0, 23, step=1, label="Hour"),
|
136 |
+
gr.Number(label="Latitude"),
|
137 |
+
gr.Number(label="Longitude"),
|
138 |
+
gr.Number(label="Panel Capacity (W)"),
|
139 |
+
gr.Number(label="Panel Efficiency (0-1)"),
|
140 |
+
gr.Number(label="Wind Speed (km/h)"),
|
141 |
+
gr.Number(label="Cloud Cover (%)"),
|
142 |
+
gr.Number(label="Temperature (°F)")
|
143 |
+
],
|
144 |
+
outputs=[
|
145 |
+
gr.Textbox(label="Results"),
|
146 |
+
gr.Image(type="numpy", label="Segmented Rooftop Area")
|
147 |
+
],
|
148 |
+
title="Solar Energy Potential and Cost Estimator",
|
149 |
+
description="Upload an image of the rooftop and enter environmental details to calculate potential solar energy, number of panels, and cost."
|
150 |
+
)
|
151 |
+
|
152 |
+
interface.launch()
|