Spaces:
Sleeping
Sleeping
| 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() | |