Tzetha's picture
Upload 2 files
34382ee verified
import streamlit as st
import torch
import cv2
import numpy as np
from ultralytics import YOLO
from PIL import Image
import easyocr
import requests
def load_model():
# Load the pre-trained YOLOv8 model for object detection
model = YOLO("yolov8n.pt") # You can use a custom-trained model for food detection
return model
def detect_ingredients(image, model):
results = model(image)
detected_items = set()
for result in results:
for box in result.boxes:
cls = result.names[int(box.cls[0])]
detected_items.add(cls)
return list(detected_items)
def extract_text(image):
# Use EasyOCR to extract text from the image
reader = easyocr.Reader(['en']) # Specify language
results = reader.readtext(np.array(image)) # Convert PIL image to NumPy
extracted_text = [text[1] for text in results] # Extract detected text
return extracted_text
MEALDB_API_URL = "https://www.themealdb.com/api/json/v1/1"
def fetch_ingredients():
"""Fetches a list of available ingredients from TheMealDB API."""
url = f"{MEALDB_API_URL}/list.php?i=list"
response = requests.get(url)
if response.status_code == 200:
data = response.json()
return [item["strIngredient"].lower() for item in data["meals"]]
return []
def filter_valid_ingredients(detected_ingredients):
"""Filters detected ingredients against TheMealDB ingredient list."""
valid_ingredients = fetch_ingredients()
return [ing for ing in detected_ingredients if ing.lower() in valid_ingredients]
def get_recipes(ingredients):
"""Fetch recipes from TheMealDB based on detected ingredients."""
recipe_list = set()
for ingredient in ingredients:
url = f"{MEALDB_API_URL}/filter.php?i={ingredient}"
response = requests.get(url)
if response.status_code == 200:
data = response.json()
if data["meals"]:
for meal in data["meals"]:
recipe_list.add(meal["strMeal"])
return list(recipe_list) if recipe_list else ["No matching recipes found."]
def main():
st.title("VQA Recipe Generator")
st.write("Upload an image of ingredients, and we'll suggest recipes you can make!")
with st.expander("How It Works"):
st.write("""
1. **Upload an Image**: Upload a photo of ingredients you have.
2. **Ingredient Detection**: The app uses a YOLOv8 model to detect visible ingredients.
3. **Text Extraction**: Any text in the image (e.g., labels) is extracted using EasyOCR.
4. **Ingredient Validation**: The detected ingredients are cross-checked with TheMealDB database.
5. **Recipe Suggestions**: The app fetches recipes that match the available ingredients.
P.S This is a work in progress so it can't cater all ingredients and can't really detect if ingredients don't have labels.
""")
model = load_model()
uploaded_file = st.file_uploader("Upload an image", type=["jpg", "png", "jpeg"])
if uploaded_file:
image = Image.open(uploaded_file)
st.image(image, caption="Uploaded Image", use_column_width=True)
# Convert image for processing
img_array = np.array(image)
img_array = cv2.cvtColor(img_array, cv2.COLOR_RGB2BGR)
with st.spinner("Detecting ingredients..."):
detected_ingredients = detect_ingredients(img_array, model)
extracted_text = extract_text(image)
# Merge OCR text with detected objects
detected_ingredients.extend(extracted_text)
# Filter only valid ingredients from TheMealDB
valid_ingredients = filter_valid_ingredients(detected_ingredients)
st.subheader("Detected Ingredients:")
st.write(", ".join(valid_ingredients))
recipes = get_recipes(valid_ingredients)
st.subheader("Suggested Recipes:")
for recipe in recipes:
st.write(f"- {recipe}")
if __name__ == "__main__":
main()