Shotocris commited on
Commit
160e36b
·
verified ·
1 Parent(s): 4939a83

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +84 -0
app.py ADDED
@@ -0,0 +1,84 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ from transformers import pipeline
3
+
4
+ #
5
+ # 1) Load a broad food classification model
6
+ # This recognizes 100+ food categories (food101).
7
+ #
8
+ food_classifier = pipeline(
9
+ "image-classification",
10
+ model="nateraw/food101"
11
+ )
12
+
13
+ def estimate_health_and_calories(dish_name: str):
14
+
15
+ dish_lower = dish_name.lower()
16
+
17
+ # Basic logic: healthy if it sounds like salad, fruit, etc.,
18
+ # less healthy if it sounds like fried, sugary, or dessert.
19
+
20
+ if any(k in dish_lower for k in ["salad", "fruit", "broccoli", "tomato", "carrot", "spinach"]):
21
+ health = 9
22
+ calories = 80
23
+ elif any(k in dish_lower for k in ["fried", "pizza", "burger", "bacon", "cream", "chips"]):
24
+ health = 3
25
+ calories = 350
26
+ elif any(k in dish_lower for k in ["cake", "pastry", "dessert", "cookie", "chocolate"]):
27
+ health = 2
28
+ calories = 400
29
+ elif any(k in dish_lower for k in ["soup", "stew", "chili"]):
30
+ health = 7
31
+ calories = 150
32
+ elif any(k in dish_lower for k in ["sandwich", "wrap", "taco"]):
33
+ health = 6
34
+ calories = 250
35
+ else:
36
+ # Default fallback
37
+ health = 5
38
+ calories = 200
39
+
40
+ return health, calories
41
+
42
+ def analyze_image(image):
43
+
44
+ # Run the model
45
+ outputs = food_classifier(image)
46
+
47
+ # Each output item is like {'label': 'omelette', 'score': 0.98}
48
+ # Sort by descending confidence (not strictly necessary if pipeline does so by default)
49
+ outputs = sorted(outputs, key=lambda x: x["score"], reverse=True)
50
+ top_label = outputs[0]["label"]
51
+ top_score = outputs[0]["score"]
52
+
53
+ # Confidence threshold to decide if it's "real food" or not
54
+ if top_score < 0.5:
55
+ return "The picture does not depict any food, please upload a different photo."
56
+
57
+ # If we pass the threshold, treat the top label as recognized dish
58
+ health_rating, cal_estimate = estimate_health_and_calories(top_label)
59
+
60
+ # Build response text
61
+ return (
62
+ f"**Food Identified**: {top_label} (confidence: {top_score:.2f})\n\n"
63
+ f"**Health Rating** (1 = extremely unhealthy, 10 = extremely healthy): **{health_rating}**\n\n"
64
+ f"**Estimated Calories**: ~{cal_estimate} kcal per serving\n\n"
65
+ )
66
+
67
+
68
+ # Build a nice Gradio interface
69
+ demo = gr.Interface(
70
+ fn=analyze_image,
71
+ inputs=gr.Image(type="pil"), # PIL image
72
+ outputs="markdown",
73
+ title="Universal Food Recognizer",
74
+ description=(
75
+ "Upload a photo of a dish or ingredient. "
76
+ "We'll attempt to recognize it (from 100+ categories) and rate how healthy it is, "
77
+ "along with a rough calorie estimate. "
78
+ "If no food is detected, you'll see an error message."
79
+ ),
80
+ allow_flagging="never", # optional: hides the 'flag' button for simpler UI
81
+ )
82
+
83
+ if __name__ == "__main__":
84
+ demo.launch()