sollar / app.py
lolzysiu's picture
Update app.py
37a3b2f verified
raw
history blame
7.16 kB
import cv2
import numpy as np
import gradio as gr
import tensorflow as tf
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
# Solar panel specifications for different types
PANEL_TYPES = {
"Monocrystalline": {"efficiency": 0.22, "cost_per_watt": 0.8},
"Polycrystalline": {"efficiency": 0.18, "cost_per_watt": 0.6},
"Thin-Film": {"efficiency": 0.12, "cost_per_watt": 0.5}
}
# Constants
AVERAGE_SUNLIGHT_HOURS_PER_DAY = 5
USD_TO_INR_CONVERSION_RATE = 83 # Convert USD to INR
# Load the pre-trained LSTM model
model = tf.keras.models.load_model('solar_energy_forecast_model.h5')
# Preprocessing image
def preprocess_image(image, clip_limit=2.0, tile_size=8):
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
clahe = cv2.createCLAHE(clipLimit=clip_limit, tileGridSize=(tile_size, tile_size))
equalized = clahe.apply(gray)
_, thresholded = cv2.threshold(equalized, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
return thresholded
# Find the roof contour
def find_roof_contour(mask, min_area=1000):
contours, _ = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
filtered_contours = [contour for contour in contours if cv2.contourArea(contour) >= min_area]
if not filtered_contours:
return None
return max(filtered_contours, key=cv2.contourArea)
# Calculate roof area
def calculate_roof_area(contour, pixel_area=0.1):
if contour is None:
return 0
return cv2.contourArea(contour) * pixel_area
# Calculate number of panels, energy, and cost
def calculate_panels_and_energy(roof_area, panel_length, panel_width, panel_type, irradiance):
panel_area = panel_length * panel_width
panel_info = PANEL_TYPES[panel_type]
panel_efficiency = panel_info["efficiency"]
# Calculate the number of panels that fit on the roof
num_panels = int(roof_area / panel_area)
# Calculate energy production per panel (in Watts)
energy_per_panel = irradiance * panel_area * panel_efficiency
total_energy_output = num_panels * energy_per_panel * AVERAGE_SUNLIGHT_HOURS_PER_DAY # daily output
total_energy_kwh = total_energy_output / 1000 # Convert to kWh
# Estimate cost of panels (in USD)
cost_per_panel = panel_area * panel_info["cost_per_watt"] * 1000
total_cost_usd = num_panels * cost_per_panel
# Convert cost to INR
total_cost_inr = total_cost_usd * USD_TO_INR_CONVERSION_RATE
return num_panels, total_energy_kwh, total_cost_inr
# Estimate yearly savings
def estimate_savings(total_energy_kwh, electricity_rate):
yearly_energy = total_energy_kwh * 365
savings = yearly_energy * electricity_rate
return savings
# Forecast future solar energy production using LSTM model
def forecast_solar_energy(historical_data):
sequence = np.array(historical_data).reshape((1, len(historical_data), 1)) # Reshape for LSTM (samples, time steps, features)
predicted_energy = model.predict(sequence)
return predicted_energy[0][0]
# Visualize the panels in a 3D layout
def visualize_roof_panels(roof_area, panel_length, panel_width, num_panels):
panel_area = panel_length * panel_width
rows = int(np.sqrt(roof_area / panel_area))
cols = num_panels // rows if rows > 0 else 1
fig = plt.figure(figsize=(8, 6))
ax = fig.add_subplot(111, projection='3d')
ax.set_title("3D Visualization of Solar Panels")
ax.set_xlabel("X")
ax.set_ylabel("Y")
ax.set_zlabel("Z")
for i in range(rows):
for j in range(cols):
x = [i, i, i + panel_length, i + panel_length]
y = [j, j + panel_width, j + panel_width, j]
z = [0, 0, 0, 0]
ax.plot_trisurf(x, y, z, color='orange', edgecolor='black')
plt.show()
return fig
# Process uploaded image and calculate solar panel details
def process_image_and_forecast(image, min_area, pixel_area, clip_limit, tile_size, panel_type, panel_length, panel_width, irradiance, electricity_rate, historical_energy_data):
if image is None:
return None, "Error: No image provided."
# Preprocess the image
preprocessed = preprocess_image(image, clip_limit, tile_size)
# Find the largest contour
roof_contour = find_roof_contour(preprocessed, min_area)
# Calculate the roof area
roof_area = calculate_roof_area(roof_contour, pixel_area)
# Calculate the number of panels, energy output, and cost
num_panels, total_energy_kwh, total_cost_inr = calculate_panels_and_energy(
roof_area, panel_length, panel_width, panel_type, irradiance
)
# Estimate yearly cost savings
yearly_savings = estimate_savings(total_energy_kwh, electricity_rate)
# Forecast future energy production using the LSTM model
try:
historical_data = list(map(float, historical_energy_data.split(','))) # Convert input to a list of floats
predicted_energy = forecast_solar_energy(historical_data)
forecast_text = f"Predicted Energy Output for Next Day: {predicted_energy:.2f} kWh"
except Exception as e:
forecast_text = f"Error in forecasting: {str(e)}"
# Draw the contour on the original image
if roof_contour is not None:
cv2.drawContours(image, [roof_contour], -1, (0, 255, 0), 2)
# Generate 3D visualization
fig = visualize_roof_panels(roof_area, panel_length, panel_width, num_panels)
# Prepare the result text
result_text = f"Roof Area: {roof_area:.2f} sq.m | Panels: {num_panels} | Energy Output: {total_energy_kwh:.2f} kWh | Cost: ₹{total_cost_inr:.2f} | Yearly Savings: ₹{yearly_savings:.2f}\n{forecast_text}"
return image, result_text, fig
# Gradio Interface with an additional input for historical energy data
interface = gr.Interface(
fn=process_image_and_forecast,
inputs=[
gr.Image(type="numpy", label="Upload Image"),
gr.Slider(500, 5000, value=1000, step=100, label="Minimum Contour Area"),
gr.Number(value=0.1, label="Pixel to Area Conversion (sq. meters)"),
gr.Slider(1.0, 5.0, value=2.0, step=0.1, label="CLAHE Clip Limit"),
gr.Slider(2, 16, value=8, step=1, label="CLAHE Tile Grid Size"),
gr.Dropdown(list(PANEL_TYPES.keys()), label="Panel Type"),
gr.Number(value=1.6, label="Panel Length (m)"),
gr.Number(value=1.0, label="Panel Width (m)"),
gr.Number(value=1000, label="Average Solar Irradiance (W/m²)"),
gr.Number(value=0.15, label="Electricity Rate (₹/kWh)"),
gr.Textbox(label="Enter Historical Energy Production (last 7 days in kWh, separated by commas)", lines=2)
],
outputs=[
gr.Image(type="numpy", label="Processed Image with Contours"),
gr.Textbox(label="Results: Roof Area, Panels, Energy, Cost, Savings, and Predictions"),
gr.Plot(label="3D Visualization of Panels")
],
title="Advanced Solar Panel Placement Estimator with Energy Forecasting",
description="Upload an image and adjust the parameters to estimate the roof area, panel placement, energy output, cost, and savings. Forecast future energy output using historical data."
)
if __name__ == '__main__':
interface.launch()