mediaportal's picture
Update app.py
b322655 verified
import os
# Force Keras 2 logic to prevent recursion/quantization errors from Kaggle .h5 files
os.environ["TF_USE_LEGACY_KERAS"] = "1"
import gradio as gr
import tensorflow as tf
import tf_keras as keras
import numpy as np
import cv2
from PIL import Image
from huggingface_hub import hf_hub_download
# --- CONFIGURATION ---
REPO_ID = "mediaportal/Roadsegmentation"
MODEL_FILENAME = "trained_model_33_cpu.h5"
# BDD100K Color Dictionary from your notebook
COLOR_DICT = {
0: (128, 128, 128), # road - gray
1: (230, 230, 50), # sidewalk - yellow
8: (50, 150, 50), # vegetation - green
10: (128, 180, 255), # sky - blue
11: (255, 0, 0), # person - red
13: (0, 0, 255), # car - blue
19: (0, 0, 0) # unknown - black
}
hf_token = os.getenv("HF_TOKEN")
model = None
def load_model():
global model
try:
path = hf_hub_download(repo_id=REPO_ID, filename=MODEL_FILENAME, token=hf_token)
# compile=False is used because the notebook uses SparseCategoricalCrossentropy
model = keras.models.load_model(path, compile=False)
return "βœ… Road Segmentation Model Loaded"
except Exception as e:
return f"❌ Error: {str(e)}"
def segment_road(img):
if model is None:
return None, None
# 1. Store original size for scaling back
h_orig, w_orig = img.shape[:2]
# 2. Preprocessing (Notebook uses 192 height, 256 width)
img_resized = cv2.resize(img, (256, 192))
img_array = img_resized.astype('float32') / 255.0
img_array = np.expand_dims(img_array, axis=0)
# 3. Predict (Returns 20 channels for 20 classes)
prediction = model.predict(img_array)[0]
# Get the class index with the highest probability for each pixel
mask = np.argmax(prediction, axis=-1).astype(np.uint8)
# 4. Create Outputs
# A. Full Semantic Map (Colorizing all classes)
full_mask_color = np.zeros((192, 256, 3), dtype=np.uint8)
for class_idx, color in COLOR_DICT.items():
full_mask_color[mask == class_idx] = color
# B. Road Highlight Overlay (Class 0 is Road)
road_mask = (mask == 0).astype(np.uint8) * 255
road_mask_resized = cv2.resize(road_mask, (w_orig, h_orig), interpolation=cv2.INTER_NEAREST)
overlay = img.copy()
overlay[road_mask_resized > 0] = [0, 255, 0] # Highlight road in green
# Blend: 70% original image, 30% green highlight
highlighted_road = cv2.addWeighted(img, 0.7, overlay, 0.3, 0)
# Resize full mask back to original aspect ratio for display
full_mask_resized = cv2.resize(full_mask_color, (w_orig, h_orig), interpolation=cv2.INTER_NEAREST)
return highlighted_road, full_mask_resized
# --- GRADIO INTERFACE ---
with gr.Blocks(theme=gr.themes.Soft()) as demo:
gr.Markdown("# πŸš— ADAS Road & Scene Segmentation")
gr.Markdown("Upload a dashboard image to identify the drivable road surface and other objects.")
status = gr.Markdown("⏳ Initializing system...")
with gr.Row():
input_img = gr.Image(label="Input Dashboard Image", type="numpy")
output_overlay = gr.Image(label="Drivable Road (Green Highlight)")
output_full = gr.Image(label="Full Semantic Map")
btn = gr.Button("Analyze Scene", variant="primary")
demo.load(load_model, outputs=status)
btn.click(fn=segment_road, inputs=input_img, outputs=[output_overlay, output_full])
if __name__ == "__main__":
demo.queue().launch()