NutriDetect / app.py
Thirupathi986's picture
Upload 4 files
dd9402a verified
Raw
History Blame Contribute Delete
7.13 kB
import streamlit as st
import os
import json
import cv2
import pandas as pd
from ultralytics import YOLO
from PIL import Image
# Configure Streamlit pages
st.set_page_config(
page_title="NutriDetect: AI-powered Food Detection and Nutritional Insights",
page_icon="🍴",
# Set layout to wide for better visualization
)
# Sidebar navigation
st.sidebar.title("Navigation")
page = st.sidebar.radio("Go to", ["Home", "Description", "Try Models"])
# Load nutritional data from the JSON file
def load_nutritional_data(json_path):
with open(json_path, 'r') as file:
data = json.load(file)
for food in data["food"]:
food["preprocessed_name"] = food["name"].lower().replace(",", "").strip()
return data
# Load models
@st.cache_resource
def load_models():
yolov8_model = YOLO("./model/Yolov8m.pt")
yolov11_model = YOLO("./model/Yolo11m.pt")
return yolov8_model, yolov11_model
# Global variables for models and nutritional data
models = load_models()
nutritional_json_path = "db.json"
nutritional_data = load_nutritional_data(nutritional_json_path)
# Home Page
if page == "Home":
st.title("🍴 NutriDetect: Food Detection and Nutritional Insights")
st.markdown("**Welcome to the NutriDetect App!** Leverage cutting-edge AI to identify food items and provide nutritional details.")
st.image("back_image.png", use_container_width=True, caption="AI-powered Food Detection")
st.subheader("🌟 Key Features")
st.markdown("""
- **Accurate Food Detection**: Identify food items in images.
- **Nutritional Insights**: Get calorie, protein, fat, and other details for detected food.
""")
# Description Page
elif page == "Description":
st.title("πŸ“– About the NutriDetect App")
st.markdown("""
The NutriDetect App uses YOLO-based models for accurate food detection and provides:
- Bounding boxes for detected food items.
- Detailed nutritional insights for the detected items.
""")
# Try Models Page
elif page == "Try Models":
st.title("🎯 Try the Models")
uploaded_file = st.file_uploader("Upload an image (jpg, jpeg, png)", type=["jpg", "jpeg", "png"])
if uploaded_file:
st.subheader("Step 2: Choose Model")
model_option = st.selectbox("Select Model", ["YOLOv8m", "YOLO11m"])
if st.button("πŸ” Detect"):
with st.spinner("Processing..."):
# Save the uploaded file temporarily
temp_file_path = "temp_image.jpg"
with open(temp_file_path, "wb") as f:
f.write(uploaded_file.getbuffer())
# Perform detection
model = models[0] if model_option == "YOLOv8m" else models[1]
results = model(temp_file_path)
# Process detected items
detected_items = []
for box in results[0].boxes.data.cpu().numpy():
label = int(box[5]) # Get the class label
class_name = model.names[label]
nutrition_info = next(
(food["nutrients"] for food in nutritional_data["food"] if food["preprocessed_name"] == class_name.lower().replace(",", "").strip()),
None
)
if nutrition_info:
detected_items.append(
{
"Food": class_name,
"Calories": round(nutrition_info.get("calories", 0), 2),
"Protein": round(nutrition_info.get("protein", 0), 2),
"Fat": round(nutrition_info.get("fat", 0), 2),
"Carbs": round(nutrition_info.get("carbs", 0), 2),
"Fiber": round(nutrition_info.get("fiber", 0), 2),
}
)
# Handle case with no detected items
if not detected_items:
st.warning("No food items detected, sorry!")
else:
# Convert detected items to DataFrame
df = pd.DataFrame(detected_items)
# Calculate totals
totals = {
"Calories": round(df["Calories"].sum(), 2),
"Protein": round(df["Protein"].sum(), 2),
"Fat": round(df["Fat"].sum(), 2),
"Carbs": round(df["Carbs"].sum(), 2),
"Fiber": round(df["Fiber"].sum(), 2),
}
# Display annotated image
annotated_image = cv2.cvtColor(results[0].plot(), cv2.COLOR_BGR2RGB)
st.image(annotated_image, caption=f"{model_option} Results", use_container_width=True)
# Two-column layout for detected items and totals
left_col, right_col = st.columns([2, 1])
# Left column: Individual food items
with left_col:
st.header("Detected Food Items")
for _, row in df.iterrows():
st.subheader(row["Food"])
st.write(f"Calories: {row['Calories']} Cal")
st.write(f"Protein: {row['Protein']} g")
st.write(f"Fat: {row['Fat']} g")
st.write(f"Carbs: {row['Carbs']} g")
st.write(f"Fiber: {row['Fiber']} g")
st.write("---")
# Right column: Total nutritional summary
# Right column: Total nutritional summary
# Right column: Total nutritional summary
with right_col:
st.header("Total Nutritional Summary")
st.metric("Total Calories", f"{totals['Calories']} Cal")
st.metric("Total Protein", f"{totals['Protein']} g")
st.metric("Total Fat", f"{totals['Fat']} g")
st.metric("Total Carbs", f"{totals['Carbs']} g")
st.metric("Total Fiber", f"{totals['Fiber']} g")
# Check for unhealthy items and provide recommendations
detected_foods = df["Food"].str.lower().tolist() # Convert to lowercase for matching
unhealthy_items = [item for item in detected_foods if item in ["pizza", "hamburger", "french fries"]]
if unhealthy_items:
st.warning(
f"Detected unhealthy food items: {', '.join(unhealthy_items)}. "
"Consider replacing them with fruits and green salad for better health. πŸ₯—πŸŽ"
)
else:
st.success("Balanced meals lead to a healthier life! 😊")