AADalhat commited on
Commit
804a5fa
Β·
verified Β·
1 Parent(s): 1cc1f50

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +161 -0
app.py ADDED
@@ -0,0 +1,161 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import tensorflow as tf
3
+ import numpy as np
4
+ from PIL import Image
5
+ import json
6
+ from datetime import datetime
7
+ import tempfile
8
+ import os
9
+ from gtts import gTTS
10
+ from fpdf import FPDF
11
+ from health_logic import generate_advice
12
+ from tensorflow.keras.applications.efficientnet import preprocess_input as efficientnet_preprocess
13
+
14
+ # Load model
15
+ model = tf.keras.models.load_model("food_vision_model.keras")
16
+
17
+ # Ensure class names are in the correct order used during training
18
+ class_names = [
19
+ "akara", "banga_soup", "egusi_soup", "jollof_rice", "moi_moi",
20
+ "nkwobi", "okpa", "suya", "tuwo", "yam_porridge"
21
+ ]
22
+
23
+ # Load food metadata
24
+ with open("food_info.json", "r") as f:
25
+ food_info = json.load(f)
26
+
27
+ # Language map for TTS
28
+ LANG_CODE = {
29
+ "English": "en",
30
+ "Hausa": "en", # gTTS doesn't support Hausa properly
31
+ "Yoruba": "en",
32
+ "Igbo": "en"
33
+ }
34
+
35
+ # Risk level helper
36
+ def get_risk_level(score):
37
+ if score <= 30:
38
+ return "🟒 Low Risk"
39
+ elif score <= 70:
40
+ return "🟑 Medium Risk"
41
+ else:
42
+ return "πŸ”΄ High Risk"
43
+
44
+ # PDF class with Unicode support
45
+ class UnicodePDF(FPDF):
46
+ def header(self):
47
+ self.set_font("DejaVu", "B", 16)
48
+ self.cell(0, 10, "HoodHealth Pro+ Report", ln=True)
49
+
50
+ def footer(self):
51
+ self.set_y(-15)
52
+ self.set_font("DejaVu", "I", 8)
53
+ self.cell(0, 10, f"Generated: {datetime.now().strftime('%Y-%m-%d %H:%M')}", align="C")
54
+
55
+ def generate_pdf(info, advice, risk_score, risk_level, flags, conditions, lang, display_name, image_path):
56
+ pdf = UnicodePDF()
57
+ pdf.add_font("DejaVu", "", "DejaVuSans.ttf", uni=True)
58
+ pdf.add_font("DejaVu", "B", "DejaVuSans.ttf", uni=True)
59
+ pdf.add_font("DejaVu", "I", "DejaVuSans.ttf", uni=True)
60
+ pdf.add_page()
61
+ pdf.set_font("DejaVu", "", 12)
62
+
63
+ pdf.image(image_path, x=10, y=40, w=60)
64
+ pdf.set_xy(75, 40)
65
+ pdf.multi_cell(0, 10, f"Food: {display_name}\nEthnicity: {info['ethnicity']}\nIngredients: {info['ingredients']}")
66
+
67
+ pdf.ln(35)
68
+ pdf.multi_cell(0, 10, f"Calories: {info['calories']} kcal\nCarbs: {info['carbs']}g\nProtein: {info['protein']}g\nFat: {info['fat']}g")
69
+ pdf.ln(5)
70
+ pdf.multi_cell(0, 10, f"Diet Type: {info['diet_type']}\nSubstitute: {info.get('substitute', 'None')}")
71
+ pdf.ln(10)
72
+
73
+ pdf.set_font("DejaVu", "B", 14)
74
+ pdf.cell(0, 10, "Health Analysis", ln=True)
75
+ pdf.set_font("DejaVu", "", 12)
76
+ pdf.multi_cell(0, 10, f"Conditions: {', '.join(conditions)}\nRisk Score: {risk_score}% ({risk_level})\nRisk Factors: {', '.join(flags) if flags else 'None'}\nAdvice: {advice}")
77
+ pdf.ln(5)
78
+ pdf.set_font("DejaVu", "I", 10)
79
+ pdf.multi_cell(0, 10, "*Note: This advice is not a medical diagnosis.*")
80
+
81
+ path = os.path.join(tempfile.gettempdir(), "report.pdf")
82
+ pdf.output(path)
83
+ return path
84
+
85
+ # Main function
86
+ def classify_food(image, conditions, language):
87
+ if not conditions:
88
+ return "⚠️ Please select at least one health condition.", None, None, None
89
+
90
+ # Preprocess image
91
+ image = image.convert("RGB").resize((224, 224))
92
+ img = tf.keras.preprocessing.image.img_to_array(image)
93
+ img = efficientnet_preprocess(img)
94
+ img = np.expand_dims(img, axis=0)
95
+
96
+ # Predict
97
+ preds = model.predict(img)[0]
98
+ idx = np.argmax(preds)
99
+ predicted_class = class_names[idx]
100
+ confidence = round(float(preds[idx]) * 100, 2)
101
+
102
+ info = food_info[predicted_class]
103
+ display_name = info.get("display_name", predicted_class.replace("_", " ").title())
104
+
105
+ # Advice logic
106
+ advice, risk_score, flags = generate_advice(info, conditions)
107
+ risk_level = get_risk_level(risk_score)
108
+
109
+ # Save audio
110
+ audio_path = os.path.join(tempfile.gettempdir(), "tts.mp3")
111
+ tts = gTTS(text=advice, lang=LANG_CODE.get(language, "en"))
112
+ tts.save(audio_path)
113
+
114
+ # Save image
115
+ image_path = os.path.join(tempfile.gettempdir(), "upload.jpg")
116
+ image.save(image_path)
117
+
118
+ # Generate PDF
119
+ pdf_path = generate_pdf(info, advice, risk_score, risk_level, flags, conditions, language, display_name, image_path)
120
+
121
+ # Output summary
122
+ result = (
123
+ f"🍽️ Food: {display_name}\n"
124
+ f"🌍 Ethnicity: {info['ethnicity']}\n"
125
+ f"πŸ₯¦ Ingredients: {info['ingredients']}\n"
126
+ f"πŸ”₯ Calories: {info['calories']} kcal\n"
127
+ f"🍞 Carbs: {info['carbs']}g\n"
128
+ f"πŸ₯© Protein: {info['protein']}g\n"
129
+ f"🧈 Fat: {info['fat']}g\n"
130
+ f"🌱 Diet Type: {info['diet_type']}\n"
131
+ f"πŸ” Substitute: {info.get('substitute', 'None')}\n\n"
132
+ f"πŸ“ˆ Confidence: {confidence}%\n"
133
+ f"πŸ“Š Risk Score: {risk_score}% ({risk_level})\n"
134
+ f"⚠️ Risk Factors: {', '.join(flags) if flags else 'None'}\n"
135
+ f"βœ… Advice: {advice}\n\n"
136
+ f"πŸ“ *Generated by HoodHealth Pro+.*"
137
+ )
138
+
139
+ return result, audio_path, f"πŸ—£οΈ Language: {language}", pdf_path
140
+
141
+ # Gradio interface
142
+ interface = gr.Interface(
143
+ fn=classify_food,
144
+ inputs=[
145
+ gr.Image(type="pil", label="Upload Food Image"),
146
+ gr.CheckboxGroup(label="Select Health Conditions", choices=[
147
+ "Normal", "Diabetic", "Hypertensive", "Weight Loss", "Malnourished", "Pregnant/Nursing", "Cholesterol Watch"]),
148
+ gr.Dropdown(label="Language for TTS", choices=["English", "Hausa", "Yoruba", "Igbo"], value="English")
149
+ ],
150
+ outputs=[
151
+ gr.Textbox(label="Prediction and Advice"),
152
+ gr.Audio(label="Hear Advice"),
153
+ gr.Textbox(label="Language Info"),
154
+ gr.File(label="Download PDF Report")
155
+ ],
156
+ title="🍲 HoodHealth Pro+",
157
+ description="Upload a food image and get nutrition details, health risk, personalized advice, audio guidance, and a downloadable PDF report."
158
+ )
159
+
160
+ if __name__ == "__main__":
161
+ interface.launch()