Amaanali01 commited on
Commit
3c5e1c4
Β·
verified Β·
1 Parent(s): f5145cb

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +232 -0
app.py ADDED
@@ -0,0 +1,232 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import tensorflow as tf
3
+ import numpy as np
4
+ from PIL import Image
5
+ import json
6
+ import os
7
+
8
+ # Page configuration
9
+ st.set_page_config(
10
+ page_title="Indian Food Classifier",
11
+ page_icon="πŸ›",
12
+ layout="wide",
13
+ initial_sidebar_state="expanded"
14
+ )
15
+
16
+ # Custom CSS for better UI
17
+ st.markdown("""
18
+ <style>
19
+ .stApp {
20
+ background-color: #f5f5f5;
21
+ }
22
+ .main-header {
23
+ text-align: center;
24
+ padding: 2rem;
25
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
26
+ color: white;
27
+ border-radius: 10px;
28
+ margin-bottom: 2rem;
29
+ }
30
+ .prediction-card {
31
+ background-color: white;
32
+ padding: 1.5rem;
33
+ border-radius: 10px;
34
+ box-shadow: 0 2px 4px rgba(0,0,0,0.1);
35
+ margin: 1rem 0;
36
+ }
37
+ .top1 {
38
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
39
+ color: white;
40
+ padding: 1rem;
41
+ border-radius: 10px;
42
+ margin: 0.5rem 0;
43
+ }
44
+ .top2 {
45
+ background-color: #e3f2fd;
46
+ padding: 0.8rem;
47
+ border-radius: 8px;
48
+ margin: 0.5rem 0;
49
+ }
50
+ .top3 {
51
+ background-color: #f3e5f5;
52
+ padding: 0.8rem;
53
+ border-radius: 8px;
54
+ margin: 0.5rem 0;
55
+ }
56
+ </style>
57
+ """, unsafe_allow_html=True)
58
+
59
+ # Load model and class names
60
+ @st.cache_resource
61
+ def load_model():
62
+ """Load the trained model"""
63
+ try:
64
+ model = tf.keras.models.load_model('dish_classifier_final.keras')
65
+ return model
66
+ except:
67
+ st.error("Model file not found! Please upload your model file.")
68
+ return None
69
+
70
+ @st.cache_data
71
+ def load_class_names():
72
+ """Load class names"""
73
+ try:
74
+ with open('class_names.json', 'r') as f:
75
+ class_names = json.load(f)
76
+ return class_names
77
+ except:
78
+ st.error("Class names file not found!")
79
+ return None
80
+
81
+ def preprocess_image(image):
82
+ """Preprocess image for model prediction"""
83
+ # Resize to 224x224
84
+ image = image.resize((224, 224))
85
+
86
+ # Convert to array
87
+ img_array = np.array(image)
88
+
89
+ # Normalize (EfficientNetV2 preprocessing)
90
+ img_array = img_array / 255.0
91
+
92
+ # Expand dimensions
93
+ img_array = np.expand_dims(img_array, axis=0)
94
+
95
+ return img_array
96
+
97
+ def predict_image(model, class_names, image):
98
+ """Make prediction"""
99
+ processed_image = preprocess_image(image)
100
+ predictions = model.predict(processed_image, verbose=0)[0]
101
+
102
+ # Get top 5 predictions
103
+ top_5_idx = np.argsort(predictions)[-5:][::-1]
104
+ top_5_labels = [class_names[idx] for idx in top_5_idx]
105
+ top_5_probs = [predictions[idx] * 100 for idx in top_5_idx]
106
+
107
+ return top_5_idx, top_5_labels, top_5_probs
108
+
109
+ def main():
110
+ # Header
111
+ st.markdown("""
112
+ <div class="main-header">
113
+ <h1>πŸ› Indian Food Classifier</h1>
114
+ <p>Upload a photo of Indian food and AI will identify it!</p>
115
+ <p style="font-size: 0.9rem; opacity: 0.9;">Supports 80+ Indian dishes with 85% Top-5 Accuracy</p>
116
+ </div>
117
+ """, unsafe_allow_html=True)
118
+
119
+ # Sidebar
120
+ with st.sidebar:
121
+ st.markdown("### πŸ“Š Model Information")
122
+ st.info("""
123
+ - **Model:** EfficientNetV2S
124
+ - **Classes:** 80 Indian Dishes
125
+ - **Accuracy:** 56.25%
126
+ - **Top-3 Accuracy:** 77.38%
127
+ - **Top-5 Accuracy:** 84.62%
128
+ """)
129
+
130
+ st.markdown("### 🍽️ Supported Dishes (Sample)")
131
+ st.markdown("""
132
+ - Butter Chicken
133
+ - Biryani (Various types)
134
+ - Dal Makhani
135
+ - Naan
136
+ - Samosa
137
+ - Gulab Jamun
138
+ - And 73 more...
139
+ """)
140
+
141
+ st.markdown("### πŸ“ How to Use")
142
+ st.markdown("""
143
+ 1. Click 'Browse files' below
144
+ 2. Upload an image of Indian food
145
+ 3. Wait for AI prediction
146
+ 4. See top 5 predictions with confidence scores
147
+ """)
148
+
149
+ st.markdown("---")
150
+ st.markdown("Made with ❀️ using TensorFlow & Streamlit")
151
+
152
+ # Main content
153
+ col1, col2 = st.columns([1, 1])
154
+
155
+ with col1:
156
+ st.markdown("### πŸ“€ Upload Image")
157
+ uploaded_file = st.file_uploader(
158
+ "Choose an image...",
159
+ type=['jpg', 'jpeg', 'png', 'webp'],
160
+ help="Upload a clear image of Indian food for best results"
161
+ )
162
+
163
+ if uploaded_file is not None:
164
+ image = Image.open(uploaded_file)
165
+ st.image(image, caption='Uploaded Image', use_container_width=True)
166
+
167
+ with col2:
168
+ if uploaded_file is not None:
169
+ st.markdown("### πŸ” Prediction Results")
170
+
171
+ with st.spinner('Analyzing your food image...'):
172
+ # Load model and class names
173
+ model = load_model()
174
+ class_names = load_class_names()
175
+
176
+ if model is not None and class_names is not None:
177
+ # Make prediction
178
+ top_5_idx, top_5_labels, top_5_probs = predict_image(model, class_names, image)
179
+
180
+ # Display results
181
+ st.markdown('<div class="prediction-card">', unsafe_allow_html=True)
182
+
183
+ # Top 1 prediction
184
+ st.markdown(f"""
185
+ <div class="top1">
186
+ <h3>πŸ₯‡ Top Prediction</h3>
187
+ <h2>{top_5_labels[0]}</h2>
188
+ <p>Confidence: {top_5_probs[0]:.2f}%</p>
189
+ </div>
190
+ """, unsafe_allow_html=True)
191
+
192
+ # Top 2 prediction
193
+ st.markdown(f"""
194
+ <div class="top2">
195
+ <strong>πŸ₯ˆ Second:</strong> {top_5_labels[1]} <br>
196
+ <span style="color: #666;">Confidence: {top_5_probs[1]:.2f}%</span>
197
+ </div>
198
+ """, unsafe_allow_html=True)
199
+
200
+ # Top 3 prediction
201
+ st.markdown(f"""
202
+ <div class="top3">
203
+ <strong>πŸ₯‰ Third:</strong> {top_5_labels[2]} <br>
204
+ <span style="color: #666;">Confidence: {top_5_probs[2]:.2f}%</span>
205
+ </div>
206
+ """, unsafe_allow_html=True)
207
+
208
+ # Top 4 & 5
209
+ st.markdown(f"""
210
+ <div style="margin-top: 1rem;">
211
+ <p><strong>4th:</strong> {top_5_labels[3]} ({top_5_probs[3]:.2f}%)</p>
212
+ <p><strong>5th:</strong> {top_5_labels[4]} ({top_5_probs[4]:.2f}%)</p>
213
+ </div>
214
+ """, unsafe_allow_html=True)
215
+
216
+ st.markdown('</div>', unsafe_allow_html=True)
217
+
218
+ # Add confidence meter
219
+ st.markdown("### πŸ“Š Confidence Meter")
220
+ st.progress(top_5_probs[0] / 100)
221
+
222
+ # Footer
223
+ st.markdown("---")
224
+ st.markdown("""
225
+ <div style="text-align: center; color: #666; font-size: 0.8rem;">
226
+ <p>⚠️ Note: Model accuracy is 56% for exact match, 85% for Top-5 predictions.<br>
227
+ For best results, use clear, well-lit images of single dishes.</p>
228
+ </div>
229
+ """, unsafe_allow_html=True)
230
+
231
+ if __name__ == "__main__":
232
+ main()