Muhammad Nabeel commited on
Commit
bd8472c
·
verified ·
1 Parent(s): fab6b36

Upload 5 files

Browse files

This app allows users to upload food images or search for recipes by name. It uses a pre-trained Gen AI model to classify the food and fetch recipe suggestions through an external API. Users can view the recipe details, including ingredients, servings, and instructions, and even download the recipe as a PDF.
Key Features:-
1) Food Image Classification: Classify food images using a machine learning model.
2) Recipe Search: Fetch recipe suggestions based on food names.
3) PDF Download: Download recipe details as a PDF with ingredients and instructions.

Files changed (5) hide show
  1. app.py +81 -0
  2. image_classifier.py +8 -0
  3. pdf_generator.py +41 -0
  4. recipe_fetcher.py +13 -0
  5. requirements.txt +6 -0
app.py ADDED
@@ -0,0 +1,81 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ from PIL import Image
3
+ from image_classifier import classify_food_with_pipeline
4
+ from recipe_fetcher import fetch_recipe
5
+ from pdf_generator import generate_pdf
6
+
7
+ # Function to display recipes in a readable format
8
+ def display_recipes(recipes):
9
+ recipe_text = ""
10
+ if recipes:
11
+ for recipe in recipes:
12
+ recipe_text += f"**Title**: {recipe['title']}\n"
13
+ recipe_text += "**Ingredients**:\n"
14
+ for ingredient in recipe['ingredients'].split('|'):
15
+ recipe_text += f"- {ingredient}\n"
16
+ recipe_text += f"**Servings**: {recipe['servings']}\n"
17
+ recipe_text += "**Instructions**:\n"
18
+ recipe_text += f"{recipe['instructions'][:300]}...\n" # Truncate for brevity
19
+ recipe_text += "-" * 40 + "\n"
20
+ else:
21
+ recipe_text = "No recipes found."
22
+
23
+ return recipe_text
24
+
25
+ # Main Streamlit app UI
26
+ def main():
27
+ st.title("Food Classifier and Recipe Finder")
28
+ st.write("Choose an option to get food recipes.")
29
+
30
+ # Radio buttons to select the mode (search or upload)
31
+ option = st.radio("Choose an option", ("Search Food Recipe", "Upload Image to Predict Food"))
32
+
33
+ # If 'Search Food Recipe' is selected
34
+ if option == "Search Food Recipe":
35
+ query = st.text_input("Enter a food name", "")
36
+ if query:
37
+ recipes = fetch_recipe(query)
38
+ recipe_text = display_recipes(recipes)
39
+ st.text_area("Recipe Details", recipe_text, height=300)
40
+
41
+ # Only show PDF download button if recipes are found
42
+ if "No recipes found." not in recipe_text:
43
+ pdf_file = generate_pdf(recipe_text, query)
44
+ with open(pdf_file, "rb") as f:
45
+ st.download_button("Download Recipe as PDF", f, file_name=pdf_file)
46
+
47
+ # If 'Upload Image to Predict Food' is selected
48
+ elif option == "Upload Image to Predict Food":
49
+ st.write("Upload an image to predict the food item and get the recipe.")
50
+
51
+ image_file = st.file_uploader("Upload an image", type=["jpg", "jpeg", "png"])
52
+
53
+ if image_file is not None:
54
+ # Open the uploaded image
55
+ image = Image.open(image_file).convert("RGB")
56
+
57
+ # Display the image
58
+ st.image(image, caption="Uploaded Image", use_container_width=True)
59
+
60
+ # Classify the food using the pipeline
61
+ label_with_pipeline = classify_food_with_pipeline(image)
62
+ st.write(f"**Predicted Food**: {label_with_pipeline}")
63
+
64
+ # Fetch the recipe based on the predicted label
65
+ recipes = fetch_recipe(label_with_pipeline)
66
+
67
+ # Display the fetched recipe(s)
68
+ recipe_text = display_recipes(recipes)
69
+ st.text_area("Recipe Details", recipe_text, height=300)
70
+
71
+ # Only show PDF download button if recipes are found
72
+ if "No recipes found." not in recipe_text:
73
+ pdf_file = generate_pdf(recipe_text, label_with_pipeline)
74
+ with open(pdf_file, "rb") as f:
75
+ st.download_button("Download Recipe as PDF", f, file_name=pdf_file)
76
+ # Add monogram at the bottom of the Streamlit app
77
+ st.markdown("<br><br><h5 style='text-align: center;'>Developed by M.Nabeel</h5>", unsafe_allow_html=True)
78
+
79
+ # Run the app
80
+ if __name__ == "__main__":
81
+ main()
image_classifier.py ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ from transformers import pipeline
2
+ from PIL import Image
3
+
4
+ # Function to classify food using the pipeline
5
+ def classify_food_with_pipeline(image: Image):
6
+ pipe = pipeline("image-classification", model="nateraw/food")
7
+ result = pipe(image)
8
+ return result[0]["label"]
pdf_generator.py ADDED
@@ -0,0 +1,41 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from fpdf import FPDF
2
+
3
+
4
+ def capitalize_first_letter(sentence):
5
+ words = sentence.split() # Split the sentence into words
6
+ capitalized_words = [word.capitalize() for word in words] # Capitalize each word's first letter
7
+ return ' '.join(capitalized_words) # Join the words back into a sentence
8
+
9
+ # Example usage:
10
+ # Function to generate PDF from recipe details
11
+ def generate_pdf(recipe_text: str, label_with_pipeline: str):
12
+ pdf = FPDF()
13
+ pdf.set_auto_page_break(auto=True, margin=15)
14
+ pdf.add_page()
15
+
16
+ sentence = label_with_pipeline
17
+ result = capitalize_first_letter(sentence)
18
+
19
+ # Set font for title
20
+ pdf.set_font("Arial", size=16, style='B')
21
+ pdf.cell(200, 10, txt=f"{result} Recipe ", ln=True, align="C")
22
+
23
+ # Add recipe details to PDF
24
+ pdf.ln(10) # Add some space
25
+ pdf.set_font("Arial", size=12)
26
+
27
+ # Add the recipe text
28
+ pdf.multi_cell(0, 10, txt=recipe_text)
29
+
30
+ # Add monogram
31
+ pdf.ln(10)
32
+ pdf.set_font("Arial", size=10)
33
+ pdf.cell(200, 10, txt="Developed by M. Nabeel", ln=True, align="C")
34
+
35
+ # Save PDF to a file
36
+
37
+
38
+ pdf_output = f"{result} Recipe.pdf"
39
+ pdf.output(pdf_output)
40
+
41
+ return pdf_output
recipe_fetcher.py ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import requests
2
+
3
+ # Function to fetch recipe based on the classified label
4
+ def fetch_recipe(query: str):
5
+ api_url = f'https://api.api-ninjas.com/v1/recipe?query={query}'
6
+ headers = {'X-Api-Key': 'Hu4DkNyaIFT+E/FfCPRaYw==EUSFTIrXpCdQXrjH'}
7
+ response = requests.get(api_url, headers=headers)
8
+
9
+ if response.status_code == requests.codes.ok:
10
+ recipes = response.json() # Convert the response to JSON
11
+ return recipes
12
+ else:
13
+ return None
requirements.txt ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ transformers==4.47.0
2
+ Pillow==11.0.0
3
+ requests==2.32.3
4
+ streamlit==1.41.0
5
+ torch==2.5.1
6
+ fpdf==1.7.2