"""
Indian/Pakistani Food Classifier
A deep learning model to identify 80+ Indian and Pakistani dishes
"""
import streamlit as st
import tensorflow as tf
import numpy as np
from PIL import Image
import json
import os
import plotly.graph_objects as go
import pandas as pd
from datetime import datetime
import random
# Page configuration
st.set_page_config(
page_title="Pakistani & Indian Food Classifier",
page_icon="🍛",
layout="wide",
initial_sidebar_state="expanded"
)
# Custom CSS for beautiful UI
st.markdown("""
""", unsafe_allow_html=True)
# ============================================================
# LOAD MODEL AND CLASSES
# ============================================================
@st.cache_resource
def load_model():
"""Load the trained model"""
try:
model = tf.keras.models.load_model('indian_food_classifier.keras')
return model
except:
try:
model = tf.keras.models.load_model('/kaggle/working/indian_food_classifier.keras')
return model
except:
st.error("⚠️ Model file not found. Please upload 'indian_food_classifier.keras'")
return None
@st.cache_data
def load_class_names():
"""Load class names"""
try:
with open('class_names.json', 'r') as f:
class_names = json.load(f)
return class_names
except:
try:
with open('/kaggle/working/class_names.json', 'r') as f:
class_names = json.load(f)
return class_names
except:
st.error("⚠️ class_names.json not found. Please upload the file.")
return None
def preprocess_image(image, target_size=(224, 224)):
"""Preprocess image for model prediction"""
if image.mode != 'RGB':
image = image.convert('RGB')
image = image.resize(target_size)
img_array = np.array(image) / 255.0
img_array = np.expand_dims(img_array, axis=0)
return img_array
def format_food_name(name):
"""Format food name for display"""
return name.replace('_', ' ').title()
def create_confidence_chart(confidences, labels, top_n=5):
"""Create an interactive confidence chart"""
fig = go.Figure(data=[
go.Bar(
x=confidences[:top_n],
y=[format_food_name(l) for l in labels[:top_n]],
orientation='h',
marker=dict(
color=confidences[:top_n],
colorscale='Greens',
showscale=True,
colorbar=dict(title="Confidence (%)")
),
text=[f"{c:.1f}%" for c in confidences[:top_n]],
textposition='outside'
)
])
fig.update_layout(
title="Top Predictions Confidence Score",
xaxis_title="Confidence (%)",
yaxis_title="Food Item",
height=400,
margin=dict(l=0, r=0, t=40, b=0),
paper_bgcolor='rgba(0,0,0,0)',
plot_bgcolor='rgba(0,0,0,0)'
)
return fig
# ============================================================
# MAIN APP
# ============================================================
def main():
# Header
st.markdown("""
""", unsafe_allow_html=True)
# Sidebar
with st.sidebar:
st.markdown("### 🏆 Model Information")
st.info("""
- **Architecture:** EfficientNetV2S
- **Classes:** 80 Indian/Pakistani Dishes
- **Accuracy:** 59.25%
- **Input Size:** 224x224 pixels
""")
st.markdown("---")
st.markdown("### 🍽️ Popular Dishes")
# Random popular dishes
popular_dishes = [
"Biryani", "Nihari", "Butter Chicken", "Aloo Gobi",
"Samosa", "Gulab Jamun", "Naan", "Haleem",
"Karahi", "Seekh Kebab", "Dal Makhani", "Ras Malai"
]
for dish in random.sample(popular_dishes, min(6, len(popular_dishes))):
st.markdown(f"• {dish}")
st.markdown("---")
st.markdown("### 📊 How It Works")
st.markdown("""
1. 📸 Upload a clear photo of food
2. 🤖 AI analyzes the image
3. 🎯 Get top 5 predictions with confidence scores
4. 📈 View detailed confidence chart
""")
st.markdown("---")
st.markdown("### 💡 Tips for Best Results")
st.markdown("""
- Use well-lit photos
- Focus on the main dish
- Avoid cluttered backgrounds
- Single dish per photo works best
""")
st.markdown("---")
st.markdown("Made with ❤️ for South Asian Cuisine")
# Main content area
col1, col2 = st.columns([1, 1])
with col1:
st.markdown("### 📤 Upload Food Image")
uploaded_file = st.file_uploader(
"Choose an image...",
type=['jpg', 'jpeg', 'png', 'webp', 'gif'],
help="Upload a clear image of Pakistani or Indian food"
)
if uploaded_file is not None:
image = Image.open(uploaded_file)
# Display image with styling
st.markdown("#### Preview")
st.image(image, caption="Uploaded Image", use_container_width=True)
# Image info
st.caption(f"📐 Image size: {image.size[0]} x {image.size[1]} pixels")
with col2:
if uploaded_file is not None:
st.markdown("### 🔍 Analysis Results")
with st.spinner("🍛 Analyzing your food image..."):
# Load model and classes
model = load_model()
class_names = load_class_names()
if model is not None and class_names is not None:
# Preprocess and predict
processed_img = preprocess_image(image)
predictions = model.predict(processed_img, verbose=0)[0]
# Get top 5 predictions
top_5_idx = np.argsort(predictions)[-5:][::-1]
top_5_names = [class_names[idx] for idx in top_5_idx]
top_5_confidences = [predictions[idx] * 100 for idx in top_5_idx]
# Display top prediction (highlighted)
st.markdown(f"""
🥇 Top Prediction
{format_food_name(top_5_names[0])}
Confidence: {top_5_confidences[0]:.2f}%
""", unsafe_allow_html=True)
# Display other predictions
st.markdown("#### Other Possibilities")
for i in range(1, min(5, len(top_5_names))):
confidence_percent = top_5_confidences[i]
# Determine emoji based on rank
if i == 1:
emoji = "🥈"
elif i == 2:
emoji = "🥉"
else:
emoji = f"{i+1}️⃣"
st.markdown(f"""
{emoji} {format_food_name(top_5_names[i])}
Confidence: {confidence_percent:.2f}%
""", unsafe_allow_html=True)
# Confidence chart
st.markdown("---")
st.markdown("### 📊 Confidence Analysis")
fig = create_confidence_chart(top_5_confidences, top_5_names, top_n=5)
st.plotly_chart(fig, use_container_width=True)
# Confidence meter for top prediction
st.markdown("#### Confidence Meter")
confidence_level = top_5_confidences[0]
if confidence_level > 70:
st.success(f"🎯 High confidence! The AI is very sure this is {format_food_name(top_5_names[0])}")
elif confidence_level > 50:
st.warning(f"🤔 Medium confidence. The AI thinks it's {format_food_name(top_5_names[0])}")
else:
st.info(f"💡 Low confidence. Try uploading a clearer photo for better results")
# Footer with additional information
st.markdown("---")
col1, col2, col3 = st.columns(3)
with col1:
st.markdown("""
### 🎯 Supported Cuisines
- Punjabi
- Mughlai
- South Indian
- Sindhi
- Kashmiri
- Hyderabadi
""")
with col2:
st.markdown("""
### 🍜 Dish Categories
- Curries & Gravies
- Rice Dishes (Biryani)
- Breads (Naan, Roti)
- Desserts & Sweets
- Snacks & Appetizers
- Beverages
""")
with col3:
st.markdown("""
### 📈 Model Performance
- 59.25% Top-1 Accuracy
- 80+ Food Classes
- 3,200 Training Images
- EfficientNetV2S Backbone
- Real-time Predictions
""")
# Footer
st.markdown("""
""", unsafe_allow_html=True)
if __name__ == "__main__":
main()