import os
import pickle
import numpy as np
import streamlit as st
import tensorflow as tf
from PIL import Image
# -------------------------------------------------
# SAYFA AYARLARI
# -------------------------------------------------
st.set_page_config(
page_title="German Traffic Sign Recognition",
page_icon="🚗",
layout="centered"
)
# -------------------------------------------------
# DOSYA YOLLARI
# app1.py, traffic_sign.h5 ve labels.pkl ana klasörde
# -------------------------------------------------
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
MODEL_PATH = os.path.join(BASE_DIR, "traffic_sign.h5")
LABEL_PATH = os.path.join(BASE_DIR, "labels.pkl")
# -------------------------------------------------
# MODEL VE LABEL YÜKLEME
# -------------------------------------------------
@st.cache_resource
def load_assets():
model = tf.keras.models.load_model(MODEL_PATH)
with open(LABEL_PATH, "rb") as file:
label_dict = pickle.load(file)
return model, label_dict
model, label_dict = load_assets()
# -------------------------------------------------
# MODELİN İSTEDİĞİ GÖRSEL BOYUTU
# -------------------------------------------------
input_shape = model.input_shape
IMG_HEIGHT = input_shape[1]
IMG_WIDTH = input_shape[2]
# -------------------------------------------------
# GÖRSEL HAZIRLAMA
# -------------------------------------------------
def prepare_image(image):
image = image.convert("RGB")
resized_image = image.resize(
(IMG_WIDTH, IMG_HEIGHT),
Image.Resampling.LANCZOS
)
image_array = np.array(resized_image, dtype=np.float32)
image_array = image_array / 255.0
image_array = np.expand_dims(image_array, axis=0)
return resized_image, image_array
# -------------------------------------------------
# LABEL OKUMA
# -------------------------------------------------
def get_label(class_id):
if isinstance(label_dict, dict):
return label_dict.get(class_id, f"Class {class_id}")
return label_dict[class_id]
# -------------------------------------------------
# TASARIM
# -------------------------------------------------
st.markdown("""
""", unsafe_allow_html=True)
st.markdown(
"
🚗 German Traffic Sign Classifier
",
unsafe_allow_html=True
)
st.markdown(
"Trafik levhası fotoğrafı çekin veya görsel yükleyin.
",
unsafe_allow_html=True
)
st.info(
"En doğru sonuç için görselde yalnızca trafik levhası görünmelidir. "
"İnternetten alınan fotoğraflarda levha küçükse önce levhayı kırpıp yükleyin."
)
st.divider()
# -------------------------------------------------
# KAMERA VE DOSYA YÜKLEME
# -------------------------------------------------
camera_file = st.camera_input("Kameradan trafik levhası çek")
uploaded_file = st.file_uploader(
"Ya da bilgisayarından trafik levhası görseli yükle",
type=["jpg", "jpeg", "png"]
)
target_file = camera_file if camera_file is not None else uploaded_file
# -------------------------------------------------
# TAHMİN
# -------------------------------------------------
if target_file is not None:
original_image = Image.open(target_file).convert("RGB")
col1, col2 = st.columns(2)
with col1:
st.image(
original_image,
caption="Yüklenen Görsel",
use_container_width=True
)
processed_image, model_input = prepare_image(original_image)
with col2:
st.image(
processed_image,
caption=f"Modelin Gördüğü Görsel ({IMG_WIDTH}x{IMG_HEIGHT})",
use_container_width=True
)
with st.spinner("Trafik levhası analiz ediliyor..."):
prediction = model.predict(model_input, verbose=0)[0]
class_id = int(np.argmax(prediction))
confidence = float(np.max(prediction) * 100)
top_3_ids = np.argsort(prediction)[-3:][::-1]
st.divider()
confidence_threshold = 80
if confidence < confidence_threshold:
st.warning(
f"Model bu görselden yeterince emin değil. Güven seviyesi: %{confidence:.2f}"
)
st.info(
"Görsel trafik levhası olmayabilir veya levha fotoğrafta çok küçük kalmış olabilir. "
"Levhanın yakın plan, net ve ortada olduğu bir görsel deneyin."
)
else:
st.markdown(
f"Tahmin: {get_label(class_id)}
",
unsafe_allow_html=True
)
st.write(f"**Güven Seviyesi:** %{confidence:.2f}")
st.progress(int(confidence))
st.subheader("En Güçlü 3 Tahmin")
for rank, idx in enumerate(top_3_ids, start=1):
label = get_label(int(idx))
score = float(prediction[idx] * 100)
st.write(
f"{rank}. **{label}** — %{score:.2f}"
)
with st.expander("Teknik Bilgiler"):
st.write(f"Model giriş boyutu: {model.input_shape}")
st.write(f"Tahmin edilen sınıf numarası: {class_id}")
st.write(f"Güven seviyesi: %{confidence:.2f}")
else:
st.info("Analiz için bir trafik levhası fotoğrafı çekin veya yükleyin.")
st.divider()
st.caption(
"Bu uygulama eğitim amaçlıdır. Model, GTSRB veri setindeki trafik işareti sınıflarına göre tahmin yapar."
)