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 Watershed Algorithm def apply_watershed(image): # Step 1: Remove shadows shadow_free_image = remove_shadows(image) # Step 2: Denoise the shadow-free image denoised = cv2.fastNlMeansDenoisingColored(shadow_free_image, None, 10, 10, 7, 21) gray = cv2.cvtColor(denoised, cv2.COLOR_BGR2GRAY) # Step 3: Thresholding _, binary = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU) # Step 4: Morphological operations to get foreground and background kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5)) sure_bg = cv2.dilate(binary, kernel, iterations=3) sure_fg = cv2.erode(binary, kernel, iterations=3) unknown = cv2.subtract(sure_bg, sure_fg) # Step 5: Marker labelling _, markers = cv2.connectedComponents(sure_fg) markers = markers + 1 markers[unknown == 255] = 0 # Step 6: Apply Watershed markers = cv2.watershed(image, markers) segmented = np.zeros_like(image) segmented[markers > 1] = image[markers > 1] return segmented, markers # Calculate Usable Roof Area # Calculate Usable Roof Area def find_usable_area(image, min_area, panel_area): segmented_image, markers = apply_watershed(image) gray = cv2.cvtColor(segmented_image, cv2.COLOR_BGR2GRAY) contours, _ = cv2.findContours(gray, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) usable_area = 0 output_image = image.copy() for contour in contours: area = cv2.contourArea(contour) if area >= min_area: usable_area += area # Mark usable area in green cv2.drawContours(output_image, [contour], -1, (0, 255, 0), 3) else: # Mark unusable area in red cv2.drawContours(output_image, [contour], -1, (0, 0, 255), 3) num_panels = usable_area // panel_area # Number of panels that fit in the usable area return usable_area, int(num_panels), output_image # Predict Irradiance def predict_irradiance(month, hour, latitude, longitude, panel_capacity, panel_efficiency, wind_speed, cloud_cover, temperature): encoded_month_hour = encoder.transform([[month, hour]]) scaled_features = scaler.transform([[latitude, longitude, panel_capacity, panel_efficiency, wind_speed, cloud_cover, temperature]]) processed_features = np.concatenate((encoded_month_hour, scaled_features), axis=1) reshaped_features = np.reshape(processed_features, (1, 1, processed_features.shape[1])) predicted_irradiance = loaded_model.predict(reshaped_features) return max(predicted_irradiance[0][0], 0.0) # Main Function def calculate_solar_energy(image, month, hour, latitude, longitude, panel_capacity, panel_efficiency, wind_speed, cloud_cover, temperature): panel_area = 7 # m² per panel min_area = 1000 # 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 = 1000 # 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()