import cv2 import numpy as np import pandas as pd import gradio as gr from keras.models import load_model from sklearn.preprocessing import OneHotEncoder, StandardScaler # Load the pre-trained model loaded_model = load_model('solar_irradiance_model.keras') # Load the dataset for encoder and scaler setup data = pd.read_csv('Solar_Irradiance.csv') data['Latitude'] = data['Latitude'].str.rstrip('°').astype(float) data['Longitude'] = data['Longitude'].str.rstrip('°').astype(float) # Features and encoder/scaler setup features = data[['Month', 'Hour', 'Latitude', 'Longitude', 'Panel_Capacity(W)', 'Panel_Efficiency', 'Wind_Speed(km/h)', 'Cloud_Cover(%)', 'temperature (°f)']] encoder = OneHotEncoder(sparse_output=False, categories='auto') categorical_features = features[['Month', 'Hour']] encoder.fit(categorical_features) scaler = StandardScaler() numerical_features = features[['Latitude', 'Longitude', 'Panel_Capacity(W)', 'Panel_Efficiency', 'Wind_Speed(km/h)', 'Cloud_Cover(%)', 'temperature (°f)']] scaler.fit(numerical_features) # Shadow Removal Function def remove_shadows(image): """Removes shadows using illumination normalization.""" gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) blurred = cv2.GaussianBlur(gray, (21, 21), 0) normalized = cv2.divide(gray, blurred, scale=255) result = cv2.cvtColor(normalized, cv2.COLOR_GRAY2BGR) return result # Preprocess Image with Canny Edge Detection def apply_canny_edge(image): # Step 1: Remove shadows shadow_free_image = remove_shadows(image) # Step 2: Convert to grayscale gray = cv2.cvtColor(shadow_free_image, cv2.COLOR_BGR2GRAY) # Step 3: Apply Canny edge detection edges = cv2.Canny(gray, 100, 200) # Step 4: Dilate the edges to make them more prominent kernel = np.ones((5, 5), np.uint8) dilated_edges = cv2.dilate(edges, kernel, iterations=2) return dilated_edges # Calculate Usable Roof Area using Flood Fill def find_usable_area(image, min_area, panel_area): edges = apply_canny_edge(image) # Apply edge detection. # Find contours from the edges contours, _ = cv2.findContours(edges, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) usable_area = 0 output_image = image.copy() # Create a copy of the input image for visualization. for contour in contours: area = cv2.contourArea(contour) # Calculate the area of each contour. if area >= min_area: usable_area += area # Add the valid area to the total usable area. cv2.drawContours(output_image, [contour], -1, (0, 255, 0), 3) # Mark usable area in green. else: cv2.drawContours(output_image, [contour], -1, (0, 0, 255), 3) # Mark unusable area in red. usable_area /= 100 # Divide the usable area by 1000 to scale it down. num_panels = usable_area // panel_area # Number of panels that fit in the usable area. return usable_area, int(num_panels), output_image def predict_irradiance(month, hour, latitude, longitude, panel_capacity, panel_efficiency, wind_speed, cloud_cover, temperature): # Ensure the month is passed as a string (e.g., "January", "February") print(f"Input month: {month}, Input hour: {hour}") # Encode the month and hour using the same encoder fitted during training encoded_month_hour = encoder.transform([[month, hour]]) # Check the shape of the encoded features print(f"Encoded month-hour features: {encoded_month_hour.shape}") # Scale the numerical features scaled_features = scaler.transform([[latitude, longitude, panel_capacity, panel_efficiency, wind_speed, cloud_cover, temperature]]) # Combine the encoded categorical features with the scaled numerical features processed_features = np.concatenate((encoded_month_hour, scaled_features), axis=1) # Reshape features to match LSTM input reshaped_features = np.reshape(processed_features, (1, 1, processed_features.shape[1])) # Predict the irradiance using the trained model predicted_irradiance = loaded_model.predict(reshaped_features) # Ensure the result is not negative return max(predicted_irradiance[0][0], 0.0) # Main Function to Calculate Solar Energy def calculate_solar_energy(image, month, hour, latitude, longitude, panel_capacity, panel_efficiency, wind_speed, cloud_cover, temperature): panel_area = 22 # m² per panel min_area = 5000 # Minimum contour area to consider for valid roof # Step 1: Find usable roof area from segmented image usable_area, num_panels, segmented_image = find_usable_area(image, min_area, panel_area) if usable_area == 0: return "No valid roof detected.", segmented_image # Step 2: Predict irradiance for the given environmental conditions irradiance = predict_irradiance(month, hour, latitude, longitude, panel_capacity, panel_efficiency, wind_speed, cloud_cover, temperature) # Step 3: Calculate potential energy and cost based on panels and irradiance potential_energy = num_panels * panel_area * irradiance * panel_efficiency # in Watts potential_energy_kwh = potential_energy / 1000 # Convert to kWh cost_per_panel = 1111 # Rs. per panel total_cost = num_panels * cost_per_panel results = (f"Usable Roof Area: {usable_area:.2f} m²\n" f"Number of Panels: {num_panels}\n" f"Predicted Irradiance: {irradiance:.2f} W/m²\n" f"Potential Solar Energy: {potential_energy_kwh:.2f} kWh\n" f"Total Cost of Panels: Rs. {total_cost}") return results, segmented_image # Gradio Interface function def interface_fn(image, month, hour, latitude, longitude, panel_capacity, panel_efficiency, wind_speed, cloud_cover, temperature): results, segmented_image = calculate_solar_energy(image, month, hour, latitude, longitude, panel_capacity, panel_efficiency, wind_speed, cloud_cover, temperature) return results, segmented_image # Gradio interface setup interface = gr.Interface( fn=interface_fn, inputs=[ gr.Image(type="numpy", label="Upload Rooftop Image"), gr.Dropdown(['January', 'february', 'march', 'april', 'may', 'june', 'july', 'august', 'september', 'october', 'november', 'december'], label="Month"), gr.Slider(0, 23, step=1, label="Hour"), gr.Number(label="Latitude"), gr.Number(label="Longitude"), gr.Number(label="Panel Capacity (W)"), gr.Number(label="Panel Efficiency (0-1)"), gr.Number(label="Wind Speed (km/h)"), gr.Number(label="Cloud Cover (%)"), gr.Number(label="Temperature (°F)") ], outputs=[ gr.Textbox(label="Results"), gr.Image(type="numpy", label="Segmented Rooftop Area") ], title="Solar Energy Potential and Cost Estimator", description="Upload an image of the rooftop and enter environmental details to calculate potential solar energy, number of panels, and cost." ) interface.launch()