ajflorez's picture
Update app.py
996e98c verified
import gradio as gr
from PIL import Image
import os
from tensorflow import keras
from keras.models import load_model
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.colors import Normalize
from io import BytesIO
import re
# import gradio
# import PIL
# import tensorflow as tf
# import numpy as np
# import matplotlib
# print("Gradio:", gradio.__version__)
# print("Pillow (PIL):", PIL.__version__)
# print("TensorFlow:", tf.__version__)
# print("NumPy:", np.__version__)
# print("Matplotlib:", matplotlib.__version__)
# Images path
path_main = 'Data/'
images_file = path_main + 'Scennarios init/Scennarios W'
# Load DL models
modelo_1ap = load_model(path_main + 'Models/modelo_1ap_app.keras')
modelo_2ap = load_model(path_main + 'Models/modelo_2ap_app.keras')
fontsize_t = 15
# Plan visualization
def load_plan_vi(mapa_seleccionado, uploaded_file):
if mapa_seleccionado == "Upload your own image" and uploaded_file is not None:
plan_image = Image.open(uploaded_file.name)
elif mapa_seleccionado == "Upload your own image" and uploaded_file is None:
# raise gradio.Warning("Deafult plan. Image was not loaded 😒.", duration=5)
image_plan_path1 = os.path.join(images_file, "80.JPG")
plan_image = Image.open(image_plan_path1)
else:
image_plan_path1 = os.path.join(images_file, mapa_seleccionado)
plan_image = Image.open(image_plan_path1)
plan_n = np.array(plan_image.convert('RGB'))
plt.imshow(plan_n)
plt.xticks(np.arange(0, 256, 50), fontsize=fontsize_t)
plt.yticks(np.arange(0, 256, 50), fontsize=fontsize_t)
plt.xlabel("X Coordinate [Pixels]", fontsize=fontsize_t)
plt.ylabel("Y Coordinate [Pixels]", fontsize=fontsize_t)
plt.show()
buf = BytesIO()
plt.savefig(buf, format='png')
buf.seek(0)
plt.close()
plan_im = Image.open(buf)
tick_positions = np.linspace(0, 256, 11)
tick_labels = ["0", "2", "4", "6", "8", "10", "12", "14", "16", "18", "20"]
plt.xticks(tick_positions, tick_labels)
buf = BytesIO()
plt.imshow(plan_n)
plt.xticks(tick_positions, tick_labels, fontsize=fontsize_t)
plt.yticks(tick_positions, tick_labels, fontsize=fontsize_t)
plt.xlabel("X Coordinate [meters]", fontsize=fontsize_t)
plt.ylabel("Y Coordinate [meters]", fontsize=fontsize_t)
plt.show()
plt.savefig(buf, format='png')
buf.seek(0)
plt.close()
plan_im_meters = Image.open(buf)
return plan_im, plan_im_meters
def validate_coords(num_aps, coords):
matches = re.findall(r"\(\s*\d+\s*,\s*\d+\s*\)", coords)
if len(matches) > int(num_aps):
new_coords = ", ".join(matches[:int(num_aps)])
return new_coords
return coords
import re
def coordinates_process(texto, interference):
a = False
texto = re.sub(r'\s*,\s*', ', ', texto) # Normalizar espacios entre comas
texto = re.sub(r'\)\s*,\s*\(', '), (', texto) # Asegurarse de que las tuplas estén separadas por "), ("
texto = texto.strip() # Eliminar cualquier espacio en exceso al principio o al final
coordinates = texto.split("), ")
resultado = []
for coord in coordinates:
try:
coord = coord.replace("(", "").replace(")", "") # Eliminar paréntesis
x, y = map(int, coord.split(",")) # Convertir a enteros
if 0 <= x <= 255 and 0 <= y <= 255:
resultado.append((x, y))
else:
a = True
except ValueError:
a = True
if a:
resultado = [(0, 0), (0, 0), (0, 0)]
while len(resultado) < 3 and interference == True:
resultado.append((0, 0))
while len(resultado) < 5 and interference == False:
resultado.append((0, 0))
return resultado # Devolver como arreglo de tuplas
# plan images path
def plan_images_list():
return [file_ for file_ in os.listdir(images_file) if file_.endswith((".JPG", ".jpg", ".jpeg", ".png", ".PNG"))]
# MAIN FUNCTION ****************************************************************
def main_function(plan_name, uploaded_file, interference = True, aps_int = 0, aps_coor = '(0,0)',
apch1 = 0, apch6 = 0, apch11 = 0, coord1 = '(0,0)', coord6 = '(0,0)', coord11 = '(0,0)'):
plan_name = str(plan_name)
interference = bool(interference)
aps_int = int(aps_int)
aps_coor = str(aps_coor)
apch1 = int(apch1)
apch6 = int(apch6)
apch11 = int(apch11)
coord1 = str(coord1)
coord6 = str(coord6)
coord11 = str(coord11)
aps_coor = validate_coords(aps_int, aps_coor)
coord1 = validate_coords(apch1, coord1)
coord6 = validate_coords(apch6, coord6)
coord11 = validate_coords(apch11, coord11)
# **************************************************************************
imagencober = {}
prediction_rgb = np.zeros((256, 256))
for k in range(5):
plt.imshow(prediction_rgb, cmap='gray')
plt.title(f'No coverage', fontsize=fontsize_t + 2)
plt.axis("off")
# plt.show()
buf = BytesIO()
plt.savefig(buf, format='png')
buf.seek(0)
plt.close()
imagencober[k] = Image.open(buf)
# **************************************************************************
# Load plan
if plan_name == "Upload your own image" and uploaded_file is not None:
plan_image = np.array(Image.open(uploaded_file.name))/255
dimensiones = plan_image.shape
if len(dimensiones) > 2:
# raise gradio.Error("Error in dimensions of the uploaded image. Must [256,256,3] 💣🎆.", duration=5)
raise ValueError("Error in image size. Must [256,256].")
plan_grayscale = plan_image[:, :, 0]
plan_in = 1 - plan_grayscale
elif plan_name == "Upload your own image" and uploaded_file is None:
# raise gradio.Warning("Deafult plan processed. Image was not loaded 😒.", duration=5)
numero = "80"
plan_in = np.array(Image.open(f"{path_main}Scennarios init/Scennarios B/{numero}.png")) / 255
else:
numero = plan_name.split('.')[0]
plan_in = np.array(Image.open(f"{path_main}Scennarios init/Scennarios B/{numero}.png")) / 255
# Some variables init
deep_count = 0
deep_coverage = []
dimension = 256
if interference:
# if apch1 == 0 and apch6 == 0 and apch11 == 0:
# raise gradio.Warning("There are not APs for estimation 😒.", duration=5)
channels_c = [1, 6 , 11]
channels = 3
num_APs = np.zeros(channels, dtype=int)
num_APs[0] = apch1
num_APs[1] = apch6
num_APs[2] = apch11
aps_chs = np.zeros((dimension, dimension, channels))
coords = [coord1, coord6, coord11]
for att, channel in enumerate(range(channels)):
if num_APs[att] > 0:
coordinates = coordinates_process(coords[att], interference)
for x, y in coordinates:
if x != 0 and y != 0:
aps_chs[int(y), int(x), att] = 1
if not interference:
channels = aps_int
aps_chs = np.zeros((dimension, dimension, 5)) # Crear la matriz
coordinates = coordinates_process(aps_coor, interference)
for att, (x, y) in enumerate(coordinates):
if x != 0 and y != 0:
aps_chs[int(y), int(x), att] = 1
# Coverage process
deep_coverage = []
ap_images = []
layer_indices = []
for k in range(channels):
capa = aps_chs[:, :, k]
filas, columnas = np.where(capa == 1)
if len(filas) == 2:
# For 2 AP
deep_count += 1
layer_1 = np.zeros_like(capa)
layer_2 = np.zeros_like(capa)
layer_1[filas[0], columnas[0]] = 1
layer_2[filas[1], columnas[1]] = 1
datos_entrada = np.stack([plan_in, layer_1, layer_2], axis=-1)
prediction = modelo_2ap.predict(datos_entrada[np.newaxis, ...])[0]
elif len(filas) == 1:
# For 1 AP
deep_count += 1
layer_1 = np.zeros_like(capa)
layer_1[filas[0], columnas[0]] = 1
datos_entrada = np.stack([plan_in, layer_1], axis=-1)
prediction = modelo_1ap.predict(datos_entrada[np.newaxis, ...])[0]
else:
# Whitout AP
prediction = np.zeros((dimension,dimension,1))
# print(prediction.shape)
deep_coverage.append(prediction)
prediction_rgb = np.squeeze((Normalize()(prediction)))
ap_images.append(prediction_rgb)
if np.all(prediction == 0):
plt.imshow(prediction_rgb, cmap='gray')
plt.title(f'No coverage', fontsize=fontsize_t)
plt.axis("off")
plt.show()
else:
plt.imshow(prediction_rgb, cmap='jet')
if interference:
plt.title(f'Coverage CH {channels_c[k]}', fontsize=fontsize_t)
cbar = plt.colorbar(ticks=np.linspace(0, 1, num=6),)
cbar.set_label('SINR [dB]', fontsize=fontsize_t)
cbar.set_ticklabels(['-3.01', '20.29', '43.60', '66.90', '90.20', '113.51'])
if not interference:
plt.title(f'Coverage AP {k}', fontsize=fontsize_t)
cbar = plt.colorbar(ticks=np.linspace(0, 1, num=6),)
cbar.set_label('Power [dBm]', fontsize=fontsize_t)
cbar.set_ticklabels(['-94.94', '-70.75', '-46.56', '-22.38', '1.81', '26.00'])
cbar.ax.tick_params(labelsize=fontsize_t)
plt.axis("off")
plt.show()
# Save the plot to a buffer
buf = BytesIO()
plt.savefig(buf, format='png')
buf.seek(0)
plt.close()
# Convert buffer to an image
imagencober[k] = Image.open(buf)
# Final coverage
if deep_coverage:
deep_coverage = np.array(deep_coverage)
nor_matrix = np.max(deep_coverage, axis=0)
celdas = np.argmax(deep_coverage, axis=0)
resultado_rgb = np.squeeze((Normalize()(nor_matrix)))
plt.imshow(resultado_rgb, cmap='jet')
cbar = plt.colorbar(ticks=np.linspace(0, 1, num=6))
if interference:
cbar.set_label('SINR [dB]', fontsize=fontsize_t)
cbar.set_ticklabels(['-3.01', '20.29', '43.60', '66.90', '90.20', '113.51'])
if not interference:
cbar.set_label('Power [dBm]', fontsize=fontsize_t)
cbar.set_ticklabels(['-94.94', '-70.75', '-46.56', '-22.38', '1.81', '26.00'])
cbar.ax.tick_params(labelsize=fontsize_t)
plt.axis("off")
plt.show()
# Save the plot to a buffer
buf = BytesIO()
plt.savefig(buf, format='png')
buf.seek(0)
plt.close()
# Convert buffer to an image
imagen3 = Image.open(buf)
# **************************************************************************
if interference == True:
if num_APs[0] > 0 and num_APs[1] > 0 and num_APs[2] > 0:
cmap = plt.cm.colors.ListedColormap(['blue', 'red', 'green'])
plt.imshow(celdas, cmap=cmap)
cbar = plt.colorbar()
cbar.set_ticks([0, 1, 2])
cbar.set_ticklabels(['1', '6', '11'])
cbar.set_label('Cell ID', fontsize=fontsize_t)
cbar.ax.tick_params(labelsize=fontsize_t)
plt.axis("off")
plt.show()
# Save the plot to a buffer
buf = BytesIO()
plt.savefig(buf, format='png')
buf.seek(0)
plt.close()
# Convert buffer to an image
imagen4 = Image.open(buf)
elif num_APs[0] > 0 and num_APs[1] > 0:
cmap = plt.cm.colors.ListedColormap(['blue', 'red'])
plt.imshow(celdas, cmap=cmap)
cbar = plt.colorbar()
cbar.set_ticks([0, 1])
cbar.set_ticklabels(['1', '6'])
cbar.set_label('Cell ID', fontsize=fontsize_t)
cbar.ax.tick_params(labelsize=fontsize_t)
plt.axis("off")
plt.show()
# Save the plot to a buffer
buf = BytesIO()
plt.savefig(buf, format='png')
buf.seek(0)
plt.close()
# Convert buffer to an image
imagen4 = Image.open(buf)
elif num_APs[0] > 0 and num_APs[2] > 0:
cmap = plt.cm.colors.ListedColormap(['blue', 'red'])
plt.imshow(celdas, cmap=cmap)
cbar = plt.colorbar()
cbar.set_ticks([0, 1])
cbar.set_ticklabels(['1', '11'])
cbar.set_label('Cell ID', fontsize=fontsize_t)
cbar.ax.tick_params(labelsize=fontsize_t)
plt.axis("off")
plt.show()
# Save the plot to a buffer
buf = BytesIO()
plt.savefig(buf, format='png')
buf.seek(0)
plt.close()
# Convert buffer to an image
imagen4 = Image.open(buf)
elif num_APs[1] > 0 and num_APs[2] > 0:
cmap = plt.cm.colors.ListedColormap(['blue', 'red'])
plt.imshow(celdas, cmap=cmap)
cbar = plt.colorbar()
cbar.set_ticks([0, 1])
cbar.set_ticklabels(['6', '11'])
cbar.set_label('Cell ID', fontsize=fontsize_t)
cbar.ax.tick_params(labelsize=fontsize_t)
plt.axis("off")
plt.show()
# Save the plot to a buffer
buf = BytesIO()
plt.savefig(buf, format='png')
buf.seek(0)
plt.close()
# Convert buffer to an image
imagen4 = Image.open(buf)
else:
cmap = plt.cm.colors.ListedColormap(['blue'])
plt.imshow(celdas, cmap=cmap)
cbar = plt.colorbar()
cbar.set_ticks([0])
cbar.set_ticklabels(['1'])
cbar.set_label('Cell ID', fontsize=fontsize_t)
cbar.ax.tick_params(labelsize=fontsize_t)
plt.axis("off")
plt.show()
# Save the plot to a buffer
buf = BytesIO()
plt.savefig(buf, format='png')
buf.seek(0)
plt.close()
# Convert buffer to an image
imagen4 = Image.open(buf)
# **************************************************************************
if interference == False:
if aps_int == 5:
cmap = plt.cm.colors.ListedColormap(['blue', 'red', 'green', 'yellow', 'violet'])
plt.imshow(celdas, cmap=cmap)
cbar = plt.colorbar()
cbar.set_ticks([0, 1, 2, 3, 4])
cbar.set_ticklabels(['1', '2', '3', '4', '5'])
cbar.set_label('Cell ID', fontsize=fontsize_t)
cbar.ax.tick_params(labelsize=fontsize_t)
plt.axis("off")
plt.show()
# Save the plot to a buffer
buf = BytesIO()
plt.savefig(buf, format='png')
buf.seek(0)
plt.close()
# Convert buffer to an image
imagen4 = Image.open(buf)
elif aps_int == 4:
cmap = plt.cm.colors.ListedColormap(['blue', 'red', 'green', 'yellow'])
plt.imshow(celdas, cmap=cmap)
cbar = plt.colorbar()
cbar.set_ticks([0, 1, 2, 3])
cbar.set_ticklabels(['1', '2', '3', '4'])
cbar.set_label('Cell ID', fontsize=fontsize_t)
cbar.ax.tick_params(labelsize=fontsize_t)
plt.axis("off")
plt.show()
# Save the plot to a buffer
buf = BytesIO()
plt.savefig(buf, format='png')
buf.seek(0)
plt.close()
# Convert buffer to an image
imagen4 = Image.open(buf)
elif aps_int == 3:
cmap = plt.cm.colors.ListedColormap(['blue', 'red', 'green'])
plt.imshow(celdas, cmap=cmap)
cbar = plt.colorbar()
cbar.set_ticks([0, 1, 2])
cbar.set_ticklabels(['1', '2', '3'])
cbar.set_label('Cell ID', fontsize=fontsize_t)
cbar.ax.tick_params(labelsize=fontsize_t)
plt.axis("off")
plt.show()
# Save the plot to a buffer
buf = BytesIO()
plt.savefig(buf, format='png')
buf.seek(0)
plt.close()
# Convert buffer to an image
imagen4 = Image.open(buf)
elif aps_int == 2:
cmap = plt.cm.colors.ListedColormap(['blue', 'red'])
plt.imshow(celdas, cmap=cmap)
cbar = plt.colorbar()
cbar.set_ticks([0, 1])
cbar.set_ticklabels(['1', '2'])
cbar.set_label('Cell ID', fontsize=fontsize_t)
cbar.ax.tick_params(labelsize=fontsize_t)
plt.axis("off")
plt.show()
# Save the plot to a buffer
buf = BytesIO()
plt.savefig(buf, format='png')
buf.seek(0)
plt.close()
# Convert buffer to an image
imagen4 = Image.open(buf)
else:
cmap = plt.cm.colors.ListedColormap(['blue'])
plt.imshow(celdas, cmap=cmap)
cbar = plt.colorbar()
cbar.set_ticks([0])
cbar.set_ticklabels(['1'])
cbar.set_label('Cell ID', fontsize=fontsize_t)
cbar.ax.tick_params(labelsize=fontsize_t)
plt.axis("off")
plt.show()
# Save the plot to a buffer
buf = BytesIO()
plt.savefig(buf, format='png')
buf.seek(0)
plt.close()
# Convert buffer to an image
imagen4 = Image.open(buf)
# **************************************************************************
return [imagencober[0], imagencober[1], imagencober[2], imagencober[3], imagencober[4], imagen3, imagen4]
def update_interface(enable_interference):
if enable_interference:
return {
map_dropdown : gr.update(visible=True),
upload_image : gr.update(visible=True),
ch1_input: gr.update(visible=True),
ch6_input: gr.update(visible=True),
ch11_input: gr.update(visible=True),
coords_ch1_input: gr.update(visible=True),
coords_ch6_input: gr.update(visible=True),
coords_ch11_input: gr.update(visible=True),
button1: gr.update(visible=True),
button2: gr.update(visible=True),
image_ap1 : gr.update(visible=False),
image_ap2 : gr.update(visible=False),
image_ch1 : gr.update(visible=True),
image_ch6 : gr.update(visible=True),
image_ch11 : gr.update(visible=True),
simple_dropdown: gr.update(visible=False),
simple_coords: gr.update(visible=False)
}
else:
return {
map_dropdown: gr.update(visible=True),
upload_image : gr.update(visible=True),
ch1_input: gr.update(visible=False),
ch6_input: gr.update(visible=False),
ch11_input: gr.update(visible=False),
coords_ch1_input: gr.update(visible=False),
coords_ch6_input: gr.update(visible=False),
coords_ch11_input: gr.update(visible=False),
simple_dropdown: gr.update(visible=True, interactive=True),
simple_coords: gr.update(visible=True, interactive=True),
image_ap1 : gr.update(visible=True),
image_ap2 : gr.update(visible=True),
image_ch1 : gr.update(visible=True),
image_ch6 : gr.update(visible=True),
image_ch11 : gr.update(visible=True)
}
with gr.Blocks() as demo:
gr.Markdown(
"""
## Fast Indoor Radio Propagation Prediction using Deep Learning
This app uses deep learning models for radio map estimation (RME) with and without interference, simulating 2.4 GHz and 5 GHz bands. RME involves estimating the received RF power based on spatial information maps.
Instructions for use:
- A predefined list of indoor floor plans is available for use.
- You can upload your own indoor floor plan.
- Negative numbers are not allowed.
- The established format for the coordinates of each access point (AP) must be followed.
- A maximum of 2 APs per channel is allowed for the interference case.
- A maximum of 5 APs is allowed for the non-interference case.
- The uploaded plan must meet the dimensions [256,256], with free spaces as white pixels and walls as black pixels.
"""
)
enable_interference = gr.Checkbox(label="Enable Interference Analysis", value=True)
with gr.Row():
with gr.Column(scale=1):
map_dropdown = gr.Dropdown(choices=plan_images_list() + ["Upload your own image"], label="Select indoor plan", value="80.JPG")
upload_image = gr.File(label="Or upload your own image", file_types=[".JPG", ".jpg", ".jpeg", ".png", ".PNG"])
ch1_input = gr.Dropdown(choices=[i for i in range(0, 3)], label="Select APs CH 1", value=0)
ch6_input = gr.Dropdown(choices=[i for i in range(0, 3)], label="Select APs CH 6", value=0)
ch11_input = gr.Dropdown(choices=[i for i in range(0, 3)], label="Select APs CH 11", value=0)
coords_ch1_input = gr.Textbox(label="Coordinate CH 1", placeholder="Format (Pixels): (x1, y1), (x2, y2)")
coords_ch6_input = gr.Textbox(label="Coordinate CH 6", placeholder="Format (Pixels): (x1, y1), (x2, y2)")
coords_ch11_input = gr.Textbox(label="Coordinate CH 11", placeholder="Format (Pixels): (x1, y1), (x2, y2)")
simple_dropdown = gr.Dropdown(choices=[str(i) for i in range(1, 6)], label="Select APs number", visible=False)
simple_coords = gr.Textbox(label="Enter APs coordinates", placeholder="Format (Pixels): (x1, y1), (x1, y1)...", visible=False,)
button1 = gr.Button("Load plan")
button2 = gr.Button("Predict coverage")
with gr.Column(scale=3):
with gr.Row():
first_image_output = gr.Image(label="Plan image pixels")
second_image_output = gr.Image(label="Plan image meters")
with gr.Row():
image_ch1 = gr.Image(label="Coverage 1")
image_ch6 = gr.Image(label="Coverage 2")
image_ch11 = gr.Image(label="Coverage 3")
image_ap1 = gr.Image(label="Coverage 4", visible=False)
image_ap2 = gr.Image(label="Coverage 5", visible=False)
with gr.Row():
image_cover_final = gr.Image(label="Final coverage")
image_cells = gr.Image(label="Cells coverage")
enable_interference.change(update_interface, inputs=[enable_interference],
outputs=[map_dropdown, upload_image,
ch1_input, ch6_input, ch11_input,
coords_ch1_input, coords_ch6_input, coords_ch11_input,
button1, button2,
simple_dropdown, simple_coords,
image_ch1, image_ch6, image_ch11,
image_ap1, image_ap2])
button1.click(load_plan_vi,
inputs=[map_dropdown, upload_image], outputs=[first_image_output, second_image_output])
# Único bloque para el clic de button2
button2.click(main_function,
inputs=[map_dropdown,
upload_image,
enable_interference,
simple_dropdown,
simple_coords,
ch1_input, ch6_input, ch11_input,
coords_ch1_input, coords_ch6_input, coords_ch11_input],
outputs=[image_ch1, image_ch6, image_ch11, image_ap1, image_ap2, image_cover_final, image_cells])
demo.launch()