File size: 5,827 Bytes
36d7b2f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
bfa5888
 
 
36d7b2f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
645b110
 
36d7b2f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
import os
import base64
from openai import OpenAI
import gradio as gr
import requests

# Set OpenAI API key
openai_api_key = os.getenv("OPENAI_API_KEY")
edamam_app_id = os.getenv("EDAMAM_APP_ID")
edamam_app_key = os.getenv("EDAMAM_API_KEY")

def encode_image(image_path):
    try:
        with open(image_path, "rb") as image_file:
            return base64.b64encode(image_file.read()).decode('utf-8')
    except Exception as e:
        raise ValueError(f"Failed to encode image: {e}")


def image_to_ingredient_list(image_path):
    """
    Transforms an image of food items/dishes into an ingredient list using GPT-4.
    
    Args:
        image_path (str): The file path to the uploaded image.
    
    Returns:
        str: The generated ingredient list or an error message.
    """
    try:
        # Encode the image to base64
        base64_image = encode_image(image_path)
        client = OpenAI(api_key=openai_api_key)
        # Prepare the message with the base64-encoded image
        messages = [
            {
                "role": "user",
                "content": [
                    {
                        "type": "text",
                        "text": """Please provide an ingredient list with estimated quantities used to make the following food image.
If the image is a drink, list the ingredients in the drink with estimated quantities based on the image.
Only estimate the quantities based on the current image not the entire food. For example if the image is a slice of cake, adjust the quantities to fit a single slice and not a whole cake.
Be confident in your answer and don't list down ingredients or quantities you are unsure of.
Only output the ingredients list with estimated quantities and separate each item with a newline.
Example:
100g rice
200g chicken breast
10ml olive oil
1 cup mango slices
1/2 cup plain yogurt
1 tablespoon peanut butter"""
                    },
                    {
                        "type": "image_url",
                        "image_url": {
                            "url":  f"data:image/jpeg;base64,{base64_image}"
                        },
                    },
                ],
            }
        ]
        
        # Call OpenAI's Chat Completion API with image
        response = client.chat.completions.create(
            model="gpt-4o-mini", 
            messages=messages
        )
        print(response.choices[0].message.content)
        # Extract the response text
        ingredient_list = response.choices[0].message.content
        
        return ingredient_list, display_nutrition(ingredient_list)
    
    except Exception as e:
        return f"Error processing image: {str(e)}", ""
    
def get_nutritional_info(ingredient_list, app_id=edamam_app_id, app_key=edamam_app_key):
    """
    Fetches nutritional information for a list of ingredients using Edamam's Nutrition Analysis API.

    Parameters:
    - ingredient_list (str): A string where each ingredient is on a new line.
    - app_id (str): Edamam application ID.
    - app_key (str): Edamam application key.

    Returns:
    - dict: Nutritional information returned by the API.
    """
    url = 'https://api.edamam.com/api/nutrition-details'
    headers = {'Content-Type': 'application/json'}
    data = {
        'title': 'Recipe',
        'ingr': ingredient_list.split('\n')
    }
    params = {
        'app_id': app_id,
        'app_key': app_key
    }
    response = requests.post(url, headers=headers, json=data, params=params)
    # response.raise_for_status()  # Raise an error for bad status codes
    return response.json()

import requests

def format_nutrition(ingredients):
    nutrition_data = get_nutritional_info(ingredients)

    # Extract relevant nutritional information
    calories = nutrition_data.get('calories', 0)
    total_nutrients = nutrition_data.get('totalNutrients', {})
    carbs = total_nutrients.get('CHOCDF', {}).get('quantity', 0)
    protein = total_nutrients.get('PROCNT', {}).get('quantity', 0)
    fats = total_nutrients.get('FAT', {}).get('quantity', 0)

    return {
        'Calories': calories,
        'Carbs': carbs,
        'Protein': protein,
        'Fats': fats
    }

def display_nutrition(ingredients):
    nutrition_info = format_nutrition(ingredients)
    return (
        f"๐Ÿ”ฅ Calories: {nutrition_info['Calories']} kcal\n"
        f"๐Ÿž Carbs: {nutrition_info['Carbs']:.2f} g\n"
        f"๐Ÿ— Protein: {nutrition_info['Protein']:.2f} g\n"
        f"๐Ÿฅ‘ Fats: {nutrition_info['Fats']:.2f} g"
    )

    
# Define Gradio interface
iface = gr.Interface(
    fn=image_to_ingredient_list,
    inputs=gr.Image(type="filepath", label="Upload Food Image"),
    outputs=[gr.Textbox(label="Ingredient List"), gr.Textbox(label="Nutritional Information")],
    title="Nutritional Estimate Demo v1",
    description="OpenAI for ingredient building and Edamam for nutritional data",
    examples=[
        ["sample_images/Picture1.jpg"],
        ["sample_images/Picture2.jpg"],
        ["sample_images/Picture3.jpg"],
        ["sample_images/Picture4.jpg"],
        ["sample_images/Picture5.jpg"],
        ["sample_images/Picture6.jpg"],
        ["sample_images/Picture7.jpg"],
        ["sample_images/Picture8.jpg"],
        ["sample_images/Picture9.jpg"],
        ["sample_images/Picture10.jpg"],
        ["sample_images/Picture11.jpg"],
        ["sample_images/Picture12.jpg"],
        ["sample_images/Picture13.jpg"],
        ["sample_images/Picture14.jpg"],
        ["sample_images/Picture15.jpg"],
        ["sample_images/Picture16.jpg"],
        ["sample_images/Picture17.jpg"],
        ["sample_images/Picture18.jpg"],
        ["sample_images/Picture19.jpg"],
        ["sample_images/Picture20.jpg"]

    ],
    allow_flagging="never"
)

# Launch the app
if __name__ == "__main__":
    iface.launch()