File size: 3,613 Bytes
e867fff
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
import streamlit as st
import numpy as np
from PIL import Image

import tensorflow as tf
from tensorflow.keras.models import load_model
from tensorflow.keras.applications.resnet50 import preprocess_input

# -----------------------------------------------------------
# 1. Config
# -----------------------------------------------------------

IMG_SIZE = (128, 128)  # zelfde als bij training
MODEL_PATH = "indian_birds_resnet50.h5"   # <-- pas aan indien nodig

# VUL HIER JOUW LABELS IN (dezelfde volgorde als tijdens training)
labels = [
    "Asian Green Bee-Eater",
    "Brown-Headed Barbet",
    "Cattle Egret",
    "Common Kingfisher",
    "Common Myna",
    "Common Rosefinch",
    "Common Tailorbird",
    "Coppersmith Barbet",
    "Forest Wagtail",
    "Gray Wagtail",
    "Hoopoe",
    "House Crow",
    "Indian Grey Hornbill",
    "Indian Peafowl",
    "Indian Pitta",
    "Indian Roller",
    "Jungle Babbler",
    "Northern Lapwing",
    "Red Wattled Lapwing",
    "Ruddy Shelduck",
    "Rufous Treepie",
    "Sarus Crane",
    "White Wagtail",
    "White-Breasted Kingfisher",
    "White-Breasted Waterhen"
]

label_map = {name: i for i, name in enumerate(labels)}
inv_label_map = {v: k for k, v in label_map.items()}

# -----------------------------------------------------------
# 2. Model laden (gecached)
# -----------------------------------------------------------

@st.cache_resource
def load_bird_model():
    model = load_model(MODEL_PATH)
    return model

model = load_bird_model()

# -----------------------------------------------------------
# 3. Hulpfuncties
# -----------------------------------------------------------

def preprocess_image(img: Image.Image) -> np.ndarray:
    """Resize + preprocess zoals bij training."""
    img = img.convert("RGB").resize(IMG_SIZE)
    x = np.array(img).astype("float32")
    x = preprocess_input(x)         # ResNet50 preprocessing
    x = np.expand_dims(x, axis=0)   # batch-dimensie
    return x

def predict_image(img: Image.Image):
    x = preprocess_image(img)
    probs = model.predict(x, verbose=0)[0]      # vorm (25,)
    pred_id = int(np.argmax(probs))
    pred_label = inv_label_map[pred_id]
    pred_prob = float(probs[pred_id])

    # top-3
    top3_ids = probs.argsort()[-3:][::-1]
    top3 = [(inv_label_map[int(i)], float(probs[i])) for i in top3_ids]

    return pred_label, pred_prob, top3

# -----------------------------------------------------------
# 4. Streamlit UI
# -----------------------------------------------------------

st.set_page_config(page_title="Indian Bird Classifier", layout="centered")

st.title("🕊️ Indian Bird Species Classifier")
st.write(
    "Upload een vogelafbeelding uit de *25 Indian Bird Species* dataset "
    "en het model (ResNet50) voorspelt de soort."
)

uploaded_file = st.file_uploader(
    "Kies een afbeelding (.jpg, .png)",
    type=["jpg", "jpeg", "png"]
)

if uploaded_file is not None:
    # Afbeelding tonen
    image = Image.open(uploaded_file)

    st.image(image, caption="Geüploade afbeelding", use_column_width=True)

    if st.button("🔮 Voorspel vogelsoort"):
        with st.spinner("Model is aan het voorspellen..."):
            pred_label, pred_prob, top3 = predict_image(image)

        st.success(f"Voorspelling: **{pred_label}** ({pred_prob:.2%} zekerheid)")

        st.subheader("Top 3 voorspellingen")
        for name, p in top3:
            st.write(f"- {name}: **{p:.2%}**")

else:
    st.info("Upload een afbeelding om te starten.")