Update app.py
Browse files
app.py
CHANGED
|
@@ -209,6 +209,35 @@ class ClimatePredictor:
|
|
| 209 |
transforms.Normalize(mean=[0.5], std=[0.5])
|
| 210 |
])
|
| 211 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 212 |
def convert_to_single_channel(self, image_array):
|
| 213 |
if len(image_array.shape) == 3:
|
| 214 |
return np.dot(image_array[...,:3], [0.2989, 0.5870, 0.1140])
|
|
@@ -292,13 +321,13 @@ class ClimatePredictor:
|
|
| 292 |
solar_map = solar_pred.cpu().numpy()[0, 0]
|
| 293 |
|
| 294 |
# ๊ฒฐ๊ณผ ์๊ฐํ
|
| 295 |
-
fig = plt.figure(figsize=(20,
|
| 296 |
|
| 297 |
-
# 1. ์๋ณธ ์ด๋ฏธ์ง์ ์์ 5% ์ด
|
| 298 |
ax1 = plt.subplot(2, 2, 1)
|
| 299 |
-
|
| 300 |
-
ax1.imshow(
|
| 301 |
-
ax1.set_title('Top 5% Potential Sites')
|
| 302 |
ax1.axis('off')
|
| 303 |
|
| 304 |
# 2. ํ๋ ฅ ๋ฐ์ ์ ์ฌ๋ ํํธ๋งต
|
|
@@ -313,13 +342,13 @@ class ClimatePredictor:
|
|
| 313 |
cbar_kws={'label': 'Solar Power Potential'})
|
| 314 |
ax3.set_title('Solar Power Potential Map')
|
| 315 |
|
| 316 |
-
# 4. ์์ 5% ํฌํ
์
|
| 317 |
ax4 = plt.subplot(2, 2, 4)
|
| 318 |
-
wind_top = np.where(
|
| 319 |
-
solar_top = np.where(
|
| 320 |
combined_map = np.stack([solar_top, wind_top, np.zeros_like(wind_map)], axis=-1)
|
| 321 |
ax4.imshow(combined_map)
|
| 322 |
-
ax4.set_title('Top 5% Potential Sites (Red: Solar, Green: Wind)')
|
| 323 |
ax4.axis('off')
|
| 324 |
|
| 325 |
plt.tight_layout()
|
|
@@ -375,18 +404,17 @@ def load_examples_from_directory(base_dir):
|
|
| 375 |
|
| 376 |
def create_gradio_interface():
|
| 377 |
predictor = ClimatePredictor('best_model.pth')
|
| 378 |
-
|
| 379 |
def process_elevation_file(file_obj):
|
| 380 |
-
if isinstance(file_obj, str):
|
| 381 |
return np.load(file_obj)
|
| 382 |
-
else:
|
| 383 |
return np.load(file_obj.name)
|
| 384 |
|
| 385 |
def predict_with_processing(*args):
|
| 386 |
rgb_image, ndvi_image, terrain_image, elevation_file = args[:4]
|
| 387 |
weather_params = args[4:]
|
| 388 |
|
| 389 |
-
# elevation ํ์ผ ์ฒ๋ฆฌ
|
| 390 |
elevation_data = process_elevation_file(elevation_file)
|
| 391 |
|
| 392 |
return predictor.predict_from_inputs(
|
|
@@ -395,36 +423,30 @@ def create_gradio_interface():
|
|
| 395 |
)
|
| 396 |
|
| 397 |
with gr.Blocks() as interface:
|
| 398 |
-
gr.
|
| 399 |
-
|
| 400 |
-
|
| 401 |
-
|
| 402 |
-
|
| 403 |
-
|
| 404 |
-
rgb_input = gr.Image(label="RGB Satellite Image", type="numpy", height=
|
| 405 |
-
ndvi_input = gr.Image(label="NDVI Image", type="numpy", height=
|
| 406 |
-
terrain_input = gr.Image(label="Terrain Map", type="numpy", height=
|
| 407 |
-
elevation_input = gr.File(label="Elevation Data (NPY
|
| 408 |
|
| 409 |
-
|
|
|
|
| 410 |
wind_speed = gr.Number(label="Wind Speed (m/s)", value=5.0)
|
| 411 |
wind_direction = gr.Number(label="Wind Direction (ยฐ)", value=180.0)
|
| 412 |
-
|
| 413 |
-
with gr.Row():
|
| 414 |
temperature = gr.Number(label="Temperature (ยฐC)", value=25.0)
|
| 415 |
humidity = gr.Number(label="Humidity (%)", value=60.0)
|
| 416 |
-
|
| 417 |
-
predict_btn = gr.Button("Generate Predictions", variant="primary")
|
| 418 |
|
| 419 |
-
# ์ถ๋ ฅ ์น์
|
| 420 |
-
|
| 421 |
-
|
| 422 |
-
|
| 423 |
-
|
| 424 |
-
examples = load_examples_from_directory("filtered_climate_data")
|
| 425 |
-
|
| 426 |
-
# ์์ ๊ฐค๋ฌ๋ฆฌ ์์ฑ
|
| 427 |
-
with gr.Row():
|
| 428 |
gr.Examples(
|
| 429 |
examples=examples,
|
| 430 |
inputs=[rgb_input, ndvi_input, terrain_input, elevation_input,
|
|
@@ -436,7 +458,6 @@ def create_gradio_interface():
|
|
| 436 |
examples_per_page=5
|
| 437 |
)
|
| 438 |
|
| 439 |
-
# ์์ธก ๋ฒํผ ํด๋ฆญ ์ด๋ฒคํธ ์ฐ๊ฒฐ
|
| 440 |
predict_btn.click(
|
| 441 |
fn=predict_with_processing,
|
| 442 |
inputs=[rgb_input, ndvi_input, terrain_input, elevation_input,
|
|
|
|
| 209 |
transforms.Normalize(mean=[0.5], std=[0.5])
|
| 210 |
])
|
| 211 |
|
| 212 |
+
def highlight_top_potential(self, rgb_image, wind_map, solar_map, percentile=95):
|
| 213 |
+
"""์์ ํฌํ
์
์ง์ญ์ ํ์ด๋ผ์ดํธ๋ก ํ์"""
|
| 214 |
+
# RGB ์ด๋ฏธ์ง๋ฅผ ๊ธฐ๋ณธ์ผ๋ก ์ฌ์ฉ
|
| 215 |
+
result = np.copy(rgb_image)
|
| 216 |
+
|
| 217 |
+
# ํํธ๋งต ๋ฆฌ์ฌ์ด์ฆ
|
| 218 |
+
h, w = rgb_image.shape[:2]
|
| 219 |
+
wind_map_resized = np.array(Image.fromarray((wind_map * 255).astype(np.uint8)).resize((w, h))) / 255.0
|
| 220 |
+
solar_map_resized = np.array(Image.fromarray((solar_map * 255).astype(np.uint8)).resize((w, h))) / 255.0
|
| 221 |
+
|
| 222 |
+
# ์์ N% ๋ง์คํฌ ์์ฑ
|
| 223 |
+
wind_threshold = np.percentile(wind_map_resized, percentile)
|
| 224 |
+
solar_threshold = np.percentile(solar_map_resized, percentile)
|
| 225 |
+
|
| 226 |
+
wind_mask = wind_map_resized >= wind_threshold
|
| 227 |
+
solar_mask = solar_map_resized >= solar_threshold
|
| 228 |
+
|
| 229 |
+
# ํ์ด๋ผ์ดํธ ์์ ์ค์
|
| 230 |
+
wind_color = np.array([0, 255, 0]) # ๋
น์
|
| 231 |
+
solar_color = np.array([255, 0, 0]) # ๋นจ๊ฐ์
|
| 232 |
+
|
| 233 |
+
# ๋ฐํฌ๋ช
์ค๋ฒ๋ ์ด ์ ์ฉ
|
| 234 |
+
alpha = 0.3
|
| 235 |
+
result[wind_mask] = result[wind_mask] * (1 - alpha) + wind_color * alpha
|
| 236 |
+
result[solar_mask] = result[solar_mask] * (1 - alpha) + solar_color * alpha
|
| 237 |
+
|
| 238 |
+
return result.astype(np.uint8)
|
| 239 |
+
|
| 240 |
+
|
| 241 |
def convert_to_single_channel(self, image_array):
|
| 242 |
if len(image_array.shape) == 3:
|
| 243 |
return np.dot(image_array[...,:3], [0.2989, 0.5870, 0.1140])
|
|
|
|
| 321 |
solar_map = solar_pred.cpu().numpy()[0, 0]
|
| 322 |
|
| 323 |
# ๊ฒฐ๊ณผ ์๊ฐํ
|
| 324 |
+
fig = plt.figure(figsize=(20, 12))
|
| 325 |
|
| 326 |
+
# 1. ์๋ณธ ์ด๋ฏธ์ง์ ์์ 5% ํ์ด๋ผ์ดํธ ์ค๋ฒ๋ ์ด
|
| 327 |
ax1 = plt.subplot(2, 2, 1)
|
| 328 |
+
highlighted_img = self.highlight_top_potential(rgb_image, wind_map, solar_map)
|
| 329 |
+
ax1.imshow(highlighted_img)
|
| 330 |
+
ax1.set_title('Top 5% Potential Sites\n(Red: Solar, Green: Wind)', pad=20)
|
| 331 |
ax1.axis('off')
|
| 332 |
|
| 333 |
# 2. ํ๋ ฅ ๋ฐ์ ์ ์ฌ๋ ํํธ๋งต
|
|
|
|
| 342 |
cbar_kws={'label': 'Solar Power Potential'})
|
| 343 |
ax3.set_title('Solar Power Potential Map')
|
| 344 |
|
| 345 |
+
# 4. ์์ 5% ํฌํ
์
๋ง ํ์ํ ํํธ๋งต
|
| 346 |
ax4 = plt.subplot(2, 2, 4)
|
| 347 |
+
wind_top = np.where(wind_map >= np.percentile(wind_map, 95), wind_map, 0)
|
| 348 |
+
solar_top = np.where(solar_map >= np.percentile(solar_map, 95), solar_map, 0)
|
| 349 |
combined_map = np.stack([solar_top, wind_top, np.zeros_like(wind_map)], axis=-1)
|
| 350 |
ax4.imshow(combined_map)
|
| 351 |
+
ax4.set_title('Top 5% Potential Sites Heatmap\n(Red: Solar, Green: Wind)', pad=20)
|
| 352 |
ax4.axis('off')
|
| 353 |
|
| 354 |
plt.tight_layout()
|
|
|
|
| 404 |
|
| 405 |
def create_gradio_interface():
|
| 406 |
predictor = ClimatePredictor('best_model.pth')
|
| 407 |
+
|
| 408 |
def process_elevation_file(file_obj):
|
| 409 |
+
if isinstance(file_obj, str):
|
| 410 |
return np.load(file_obj)
|
| 411 |
+
else:
|
| 412 |
return np.load(file_obj.name)
|
| 413 |
|
| 414 |
def predict_with_processing(*args):
|
| 415 |
rgb_image, ndvi_image, terrain_image, elevation_file = args[:4]
|
| 416 |
weather_params = args[4:]
|
| 417 |
|
|
|
|
| 418 |
elevation_data = process_elevation_file(elevation_file)
|
| 419 |
|
| 420 |
return predictor.predict_from_inputs(
|
|
|
|
| 423 |
)
|
| 424 |
|
| 425 |
with gr.Blocks() as interface:
|
| 426 |
+
with gr.Column():
|
| 427 |
+
gr.Markdown("# Renewable Energy Potential Predictor")
|
| 428 |
+
|
| 429 |
+
# ์
๋ ฅ ์น์
- ๋ชจ๋ ์
๋ ฅ์ ํ๋์ Row์ ๋ฐฐ์น
|
| 430 |
+
with gr.Row(equal_height=True):
|
| 431 |
+
# ์ด๋ฏธ์ง/ํ์ผ ์
๋ ฅ
|
| 432 |
+
rgb_input = gr.Image(label="RGB Satellite Image", type="numpy", height=150, scale=1)
|
| 433 |
+
ndvi_input = gr.Image(label="NDVI Image", type="numpy", height=150, scale=1)
|
| 434 |
+
terrain_input = gr.Image(label="Terrain Map", type="numpy", height=150, scale=1)
|
| 435 |
+
elevation_input = gr.File(label="Elevation Data (NPY)", height=150, scale=1)
|
| 436 |
|
| 437 |
+
# ๋ ์จ ํ๋ผ๋ฏธํฐ ์
๋ ฅ
|
| 438 |
+
with gr.Column(scale=1):
|
| 439 |
wind_speed = gr.Number(label="Wind Speed (m/s)", value=5.0)
|
| 440 |
wind_direction = gr.Number(label="Wind Direction (ยฐ)", value=180.0)
|
|
|
|
|
|
|
| 441 |
temperature = gr.Number(label="Temperature (ยฐC)", value=25.0)
|
| 442 |
humidity = gr.Number(label="Humidity (%)", value=60.0)
|
| 443 |
+
predict_btn = gr.Button("Generate Predictions", variant="primary", size="lg")
|
|
|
|
| 444 |
|
| 445 |
+
# ์ถ๋ ฅ ์น์
- ์ ์ฒด ๋๋น ์ฌ์ฉ
|
| 446 |
+
output_plot = gr.Plot(label="Prediction Results", container=True, height=600)
|
| 447 |
+
|
| 448 |
+
# ์์ ์น์
|
| 449 |
+
examples = load_examples_from_directory("filtered_climate_data")
|
|
|
|
|
|
|
|
|
|
|
|
|
| 450 |
gr.Examples(
|
| 451 |
examples=examples,
|
| 452 |
inputs=[rgb_input, ndvi_input, terrain_input, elevation_input,
|
|
|
|
| 458 |
examples_per_page=5
|
| 459 |
)
|
| 460 |
|
|
|
|
| 461 |
predict_btn.click(
|
| 462 |
fn=predict_with_processing,
|
| 463 |
inputs=[rgb_input, ndvi_input, terrain_input, elevation_input,
|