Create app.py
Browse files
app.py
ADDED
@@ -0,0 +1,151 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# Import necessary libraries
|
2 |
+
import gradio as gr
|
3 |
+
import wget
|
4 |
+
from transformers import pipeline
|
5 |
+
import requests
|
6 |
+
|
7 |
+
# Nutritionix API setup
|
8 |
+
api_url = "https://trackapi.nutritionix.com/v2/natural/nutrients"
|
9 |
+
|
10 |
+
# App ID, App Key provided by Nutritionix
|
11 |
+
headers = {
|
12 |
+
"x-app-id": "dd773727",
|
13 |
+
"x-app-key": "86f278fc4c7f276c386f280848acf3e6",
|
14 |
+
}
|
15 |
+
|
16 |
+
# Load the Models
|
17 |
+
|
18 |
+
# Load the BLIP VQA Model (Recognize the food)
|
19 |
+
visual_quest_ans = pipeline("visual-question-answering", model="Salesforce/blip-vqa-base")
|
20 |
+
|
21 |
+
# Load the Translation Model (English to Arabic)
|
22 |
+
translation_eng_to_ar = pipeline("translation_en_to_ar", model="marefa-nlp/marefa-mt-en-ar")
|
23 |
+
|
24 |
+
# Function to recognize food from the image using the VQA model
|
25 |
+
def food_recognizer(image):
|
26 |
+
# Pass the image and the question to the model to identify the food on the image
|
27 |
+
result = visual_quest_ans(image=image, question="What is the food or the drink in the image?")
|
28 |
+
return result[0]['answer']
|
29 |
+
|
30 |
+
# Function to fetch nutritional information from Nutritionix API
|
31 |
+
def nutrition_info(food):
|
32 |
+
# Prepare the data for the API request
|
33 |
+
data = {
|
34 |
+
"query": food,
|
35 |
+
"timezone": "US/Eastern"
|
36 |
+
}
|
37 |
+
|
38 |
+
# Send a POST request to the Nutritionix API with the food item
|
39 |
+
response = requests.post(api_url, headers=headers, json=data)
|
40 |
+
|
41 |
+
# Get the nutritional information in JSON format
|
42 |
+
nutritions = response.json()
|
43 |
+
return nutritions
|
44 |
+
|
45 |
+
# Function to translate text from English to Arabic with preprocessing
|
46 |
+
def translator(text):
|
47 |
+
text = text.strip() # Remove leading/trailing spaces
|
48 |
+
result = translation_eng_to_ar(text) # Use the translation model to translate the text
|
49 |
+
result = result[0]['translation_text']
|
50 |
+
return result
|
51 |
+
|
52 |
+
# Function to process food recognition and get nutrition info
|
53 |
+
def process_food_result(image, language):
|
54 |
+
# Recognize the food item in the uploaded image
|
55 |
+
food_item = food_recognizer(image)
|
56 |
+
|
57 |
+
# Fetch nutritional information for the recognized food item
|
58 |
+
nutritions_info = nutrition_info(food_item)
|
59 |
+
|
60 |
+
# Extract nutritional information
|
61 |
+
food_info = nutritions_info['foods'][0]
|
62 |
+
calories = food_info['nf_calories']
|
63 |
+
protein = food_info['nf_protein']
|
64 |
+
carbs = food_info['nf_total_carbohydrate']
|
65 |
+
fat = food_info['nf_total_fat']
|
66 |
+
# Use 'Unknown' if value is not available
|
67 |
+
sugars = food_info.get('nf_sugars', 'Unknown')
|
68 |
+
fiber = food_info.get('nf_dietary_fiber', 'Unknown')
|
69 |
+
sodium = food_info.get('nf_sodium', 'Unknown')
|
70 |
+
serving_size = food_info.get('serving_weight_grams', 'Unknown')
|
71 |
+
|
72 |
+
# Identify if the food item is a liquid (simple check for common drink categories)
|
73 |
+
liquid_keywords = ['juice', 'water', 'milk', 'soda', 'tea', 'coffee']
|
74 |
+
is_liquid = any(keyword in food_item.lower() for keyword in liquid_keywords)
|
75 |
+
|
76 |
+
# Convert serving size to milliliters if it's a liquid
|
77 |
+
if is_liquid and serving_size != 'Unknown':
|
78 |
+
serving_size_ml = serving_size # Assume 1 gram ≈ 1 milliliter for liquids
|
79 |
+
serving_size_text_en = f"{serving_size_ml} mL"
|
80 |
+
serving_size_text_ar = f"{serving_size_ml} مل"
|
81 |
+
else:
|
82 |
+
serving_size_text_en = f"{serving_size} grams"
|
83 |
+
serving_size_text_ar = f"{serving_size} جرام"
|
84 |
+
|
85 |
+
# Generate output in the selected language
|
86 |
+
if language == "Arabic":
|
87 |
+
# Translate the food item name to Arabic
|
88 |
+
food_item_ar = translator(food_item)
|
89 |
+
output_ar = f"""
|
90 |
+
<div style='direction: rtl; text-align: right;'>
|
91 |
+
<b>الطعام</b>: {food_item_ar}<br>
|
92 |
+
<b>حجم الحصة</b>: {serving_size_text_ar}<br>
|
93 |
+
<b>السعرات الحرارية</b>: {calories} كيلو كالوري<br>
|
94 |
+
<b>البروتين</b>: {protein} جرام<br>
|
95 |
+
<b>الكربوهيدرات</b>: {carbs} جرام<br>
|
96 |
+
<b>السكر</b>: {sugars} جرام<br>
|
97 |
+
<b>الألياف</b>: {fiber} جرام<br>
|
98 |
+
<b>الصوديوم</b>: {sodium} مجم<br>
|
99 |
+
<b>الدهون</b>: {fat} جرام
|
100 |
+
</div>
|
101 |
+
"""
|
102 |
+
return output_ar
|
103 |
+
else:
|
104 |
+
# For English output
|
105 |
+
output_en = f"""
|
106 |
+
<div style='text-align: left;'>
|
107 |
+
<b>Food</b>: {food_item}<br>
|
108 |
+
<b>Serving Size</b>: {serving_size_text_en}<br>
|
109 |
+
<b>Calories</b>: {calories} kcal<br>
|
110 |
+
<b>Protein</b>: {protein}g<br>
|
111 |
+
<b>Carbohydrates</b>: {carbs}g<br>
|
112 |
+
<b>Sugars</b>: {sugars}g<br>
|
113 |
+
<b>Fiber</b>: {fiber}g<br>
|
114 |
+
<b>Sodium</b>: {sodium}mg<br>
|
115 |
+
<b>Fat</b>: {fat}g
|
116 |
+
</div>
|
117 |
+
"""
|
118 |
+
return output_en
|
119 |
+
|
120 |
+
|
121 |
+
# Gradio interface function
|
122 |
+
def gradio_function(image, language):
|
123 |
+
# Call the process_food_result function to get the output
|
124 |
+
result = process_food_result(image, language)
|
125 |
+
return result
|
126 |
+
|
127 |
+
# Define URLs of example images
|
128 |
+
image_urls = [
|
129 |
+
"https://raw.githubusercontent.com/Abdulrahman078/ML_Datasets-Imgs-Vids/main/close-up-delicious-pizza.jpg",
|
130 |
+
"https://raw.githubusercontent.com/Abdulrahman078/ML_Datasets-Imgs-Vids/main/assorted-desserts-with-chocolate-frosted-pink-glazed-sprinkles.jpg",
|
131 |
+
"https://raw.githubusercontent.com/Abdulrahman078/ML_Datasets-Imgs-Vids/main/fried-fish-with-cranberries-wooden-board.jpg",
|
132 |
+
"https://raw.githubusercontent.com/Abdulrahman078/ML_Datasets-Imgs-Vids/main/glass-water.jpg"
|
133 |
+
]
|
134 |
+
|
135 |
+
# Download the images and use their paths
|
136 |
+
example_images = [wget.download(url) for url in image_urls]
|
137 |
+
|
138 |
+
|
139 |
+
# Setup the Gradio interface
|
140 |
+
iface = gr.Interface(
|
141 |
+
fn=gradio_function, # Function to call
|
142 |
+
inputs=[gr.Image(type="pil", label="Upload an image"), # Input: Image (in PIL format)
|
143 |
+
gr.Dropdown(choices=["Arabic", "English"], label="Select Language", value="Arabic")], # Input: Dropdown for language selection
|
144 |
+
outputs=gr.HTML(label="Food and Nutrition Information"), # Output: HTML for displaying nutrition info
|
145 |
+
title="Bilingual Food Recognition and Nutrition Info Tool", # Title of the Gradio interface
|
146 |
+
description="Upload an image of food, and the tool will recognize it and provide nutritional information in both English or Arabic languages.", # Description of the tool
|
147 |
+
examples=[[img] for img in example_images] # Add examples with the image and language
|
148 |
+
)
|
149 |
+
|
150 |
+
# Launch the Gradio interface with debug mode enabled
|
151 |
+
iface.launch(debug=True)
|