Spaces:
Runtime error
Runtime error
Update app.py
Browse files
app.py
CHANGED
|
@@ -1,130 +1,72 @@
|
|
| 1 |
-
|
| 2 |
-
import
|
| 3 |
-
from flask import Flask, request, jsonify
|
| 4 |
from PIL import Image
|
| 5 |
import tensorflow as tf
|
| 6 |
import numpy as np
|
| 7 |
from tensorflow.keras.applications.efficientnet import preprocess_input
|
| 8 |
-
|
| 9 |
-
import google.generativeai as genai
|
| 10 |
from io import BytesIO
|
| 11 |
-
|
| 12 |
-
|
| 13 |
-
|
| 14 |
-
os.environ["TF_ENABLE_ONEDNN_OPTS"] = "0"
|
| 15 |
|
| 16 |
# Load environment variables
|
| 17 |
load_dotenv()
|
| 18 |
GOOGLE_API_KEY = os.getenv("GOOGLE_API_KEY")
|
| 19 |
-
if not GOOGLE_API_KEY:
|
| 20 |
-
raise Exception("Google API key not found. Set it in your .env file")
|
| 21 |
genai.configure(api_key=GOOGLE_API_KEY)
|
| 22 |
|
| 23 |
-
# Load
|
| 24 |
IMG_SIZE = (299, 299)
|
| 25 |
-
if not os.path.exists("model.h5"):
|
| 26 |
-
raise Exception("Model file model.h5 not found in repo!")
|
| 27 |
model = tf.keras.models.load_model("model.h5")
|
| 28 |
-
model.summary()
|
| 29 |
-
|
| 30 |
with open("trained_classes.json", "r") as f:
|
| 31 |
class_labels = json.load(f)
|
| 32 |
|
| 33 |
-
|
| 34 |
-
|
| 35 |
-
|
| 36 |
-
|
| 37 |
-
|
| 38 |
-
|
| 39 |
-
|
| 40 |
-
|
| 41 |
-
|
| 42 |
-
|
| 43 |
-
|
| 44 |
-
|
| 45 |
-
|
| 46 |
-
|
| 47 |
-
|
| 48 |
-
|
| 49 |
-
|
| 50 |
-
|
| 51 |
-
|
| 52 |
-
|
| 53 |
-
img_array = preprocess_input(img_array)
|
| 54 |
-
img_array = np.expand_dims(img_array, axis=0)
|
| 55 |
-
|
| 56 |
-
predictions = model.predict(img_array)
|
| 57 |
-
predicted_index = np.argmax(predictions[0])
|
| 58 |
-
confidence = float(predictions[0][predicted_index])
|
| 59 |
-
|
| 60 |
-
predicted_food = class_labels[predicted_index] if predicted_index < len(class_labels) else "unknown"
|
| 61 |
-
return predicted_food, confidence
|
| 62 |
-
except Exception as e:
|
| 63 |
-
print("Prediction error:", e)
|
| 64 |
-
return "unknown", 0.0
|
| 65 |
-
|
| 66 |
-
def input_image_setup(uploaded_file):
|
| 67 |
-
try:
|
| 68 |
-
return [{"mime_type": "image/jpeg", "data": uploaded_file.read()}]
|
| 69 |
-
except Exception as e:
|
| 70 |
-
print("Error in input_image_setup:", e)
|
| 71 |
-
return []
|
| 72 |
-
|
| 73 |
-
def get_gemini_response(food_item, image_data, prompt):
|
| 74 |
try:
|
| 75 |
model_gemini = genai.GenerativeModel("gemini-1.5-flash-latest")
|
| 76 |
-
response = model_gemini.generate_content([food_item,
|
| 77 |
return response.text
|
| 78 |
except Exception as e:
|
| 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 |
-
prompt = (
|
| 105 |
-
f"Analyze the nutritional content of {predicted_food}. "
|
| 106 |
-
"Provide estimated values for Calories, Protein (g), Carbohydrates (g), Fats (g), Fiber (g), and Sugars (g) "
|
| 107 |
-
"along with short dietary recommendations. Do not use bold formatting."
|
| 108 |
-
if predicted_food != "unknown" and confidence >= confidence_threshold
|
| 109 |
-
else "Analyze the nutritional content of food. Provide estimated values only."
|
| 110 |
-
)
|
| 111 |
-
|
| 112 |
-
nutritional_response = get_gemini_response(predicted_food, image_data, prompt)
|
| 113 |
-
|
| 114 |
-
return jsonify({
|
| 115 |
-
"predicted_food": predicted_food,
|
| 116 |
-
"confidence": confidence,
|
| 117 |
-
"nutritional_info": nutritional_response
|
| 118 |
-
})
|
| 119 |
-
|
| 120 |
-
except Exception as e:
|
| 121 |
-
print("Error processing image:", e)
|
| 122 |
-
return jsonify({"error": str(e)}), 500
|
| 123 |
-
|
| 124 |
-
@app.route("/ping", methods=["GET"])
|
| 125 |
-
def ping():
|
| 126 |
-
return jsonify({"message": "pong"})
|
| 127 |
-
|
| 128 |
-
if __name__ == "__main__":
|
| 129 |
-
app.run(debug=True, host="0.0.0.0", port=5000)
|
| 130 |
-
|
|
|
|
| 1 |
+
# app.py
|
| 2 |
+
import streamlit as st
|
|
|
|
| 3 |
from PIL import Image
|
| 4 |
import tensorflow as tf
|
| 5 |
import numpy as np
|
| 6 |
from tensorflow.keras.applications.efficientnet import preprocess_input
|
| 7 |
+
import json
|
|
|
|
| 8 |
from io import BytesIO
|
| 9 |
+
import google.generativeai as genai
|
| 10 |
+
from dotenv import load_dotenv
|
| 11 |
+
import os
|
|
|
|
| 12 |
|
| 13 |
# Load environment variables
|
| 14 |
load_dotenv()
|
| 15 |
GOOGLE_API_KEY = os.getenv("GOOGLE_API_KEY")
|
|
|
|
|
|
|
| 16 |
genai.configure(api_key=GOOGLE_API_KEY)
|
| 17 |
|
| 18 |
+
# Load model
|
| 19 |
IMG_SIZE = (299, 299)
|
|
|
|
|
|
|
| 20 |
model = tf.keras.models.load_model("model.h5")
|
|
|
|
|
|
|
| 21 |
with open("trained_classes.json", "r") as f:
|
| 22 |
class_labels = json.load(f)
|
| 23 |
|
| 24 |
+
# Streamlit UI
|
| 25 |
+
st.title("NutriSync: Food Nutrition Analyzer")
|
| 26 |
+
uploaded_file = st.file_uploader("Upload food image", type=["jpg","jpeg","png"])
|
| 27 |
+
|
| 28 |
+
def predict_food(img):
|
| 29 |
+
img = img.resize(IMG_SIZE)
|
| 30 |
+
img_array = np.array(img)
|
| 31 |
+
if len(img_array.shape) == 2:
|
| 32 |
+
img_array = np.stack((img_array,) * 3, axis=-1)
|
| 33 |
+
if img_array.shape[-1] == 4:
|
| 34 |
+
img_array = img_array[..., :3]
|
| 35 |
+
img_array = preprocess_input(img_array)
|
| 36 |
+
img_array = np.expand_dims(img_array, axis=0)
|
| 37 |
+
preds = model.predict(img_array)
|
| 38 |
+
idx = np.argmax(preds[0])
|
| 39 |
+
confidence = float(preds[0][idx])
|
| 40 |
+
food = class_labels[idx] if idx < len(class_labels) else "unknown"
|
| 41 |
+
return food, confidence
|
| 42 |
+
|
| 43 |
+
def get_gemini_response(food_item, img_bytes, prompt):
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 44 |
try:
|
| 45 |
model_gemini = genai.GenerativeModel("gemini-1.5-flash-latest")
|
| 46 |
+
response = model_gemini.generate_content([food_item, {"mime_type":"image/jpeg","data":img_bytes}, prompt])
|
| 47 |
return response.text
|
| 48 |
except Exception as e:
|
| 49 |
+
return f"Error retrieving nutritional info: {e}"
|
| 50 |
+
|
| 51 |
+
if uploaded_file is not None:
|
| 52 |
+
img = Image.open(uploaded_file).convert("RGB")
|
| 53 |
+
st.image(img, caption="Uploaded Image", use_column_width=True)
|
| 54 |
+
|
| 55 |
+
food, confidence = predict_food(img)
|
| 56 |
+
st.write(f"Predicted Food: {food}, Confidence: {confidence:.2f}")
|
| 57 |
+
|
| 58 |
+
# Reset file pointer for Gemini
|
| 59 |
+
uploaded_file.seek(0)
|
| 60 |
+
img_bytes = uploaded_file.read()
|
| 61 |
+
|
| 62 |
+
prompt = (
|
| 63 |
+
f"Analyze the nutritional content of {food}. "
|
| 64 |
+
"Provide estimated values for Calories, Protein (g), Carbs (g), Fats (g), Fiber (g), Sugars (g) "
|
| 65 |
+
"with short dietary recommendations."
|
| 66 |
+
if food != "unknown" and confidence >= 0.6
|
| 67 |
+
else "Analyze the nutritional content of food. Provide estimated values only."
|
| 68 |
+
)
|
| 69 |
+
|
| 70 |
+
nutrition_info = get_gemini_response(food, img_bytes, prompt)
|
| 71 |
+
st.write("Nutritional Info:")
|
| 72 |
+
st.write(nutrition_info)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|