FoodHealth-pro / app.py
AADalhat's picture
Update app.py
a8434d9 verified
raw
history blame
5.93 kB
import gradio as gr
import tensorflow as tf
import numpy as np
from PIL import Image
import json
from gtts import gTTS
import os
import tempfile
from health_logic import generate_advice
from deep_translator import GoogleTranslator
from datetime import datetime
from fpdf import FPDF
# Load model
model = tf.keras.models.load_model("food_vision_model.keras")
# Load metadata
with open("food_info.json", "r") as f:
food_info = json.load(f)
class_names = list(food_info.keys())
# Language code mapping for gTTS
LANG_CODE = {
"English": "en",
"Hausa": "ha",
"Yoruba": "yo",
"Igbo": "ig"
}
# Risk color level
def get_risk_level(score):
if score <= 30:
return "🟒 Low Risk"
elif score <= 70:
return "🟑 Medium Risk"
else:
return "πŸ”΄ High Risk"
# PDF Generator using Unicode-safe font
class UnicodePDF(FPDF):
def __init__(self):
super().__init__()
self.add_font("DejaVu", "", "DejaVuSans.ttf", uni=True)
self.add_font("DejaVu", "B", "DejaVuSans.ttf", uni=True)
self.set_font("DejaVu", size=12)
def generate_pdf(info, advice, risk_score, risk_level, flags, conditions, lang, display_name, image_path):
pdf = UnicodePDF()
pdf.add_page()
pdf.set_font("DejaVu", "B", 16)
pdf.cell(0, 10, "HoodHealth Pro+ Report", ln=True)
pdf.set_font("DejaVu", size=12)
pdf.cell(0, 10, f"Date: {datetime.now().strftime('%Y-%m-%d %H:%M')}", ln=True)
pdf.ln(10)
if os.path.exists(image_path):
pdf.image(image_path, x=10, y=40, w=60)
pdf.set_xy(75, 40)
pdf.multi_cell(0, 10,
f"🍽️ Food: {display_name}\n"
f"🌍 Ethnicity: {info['ethnicity']}\n"
f"πŸ₯¦ Ingredients: {info['ingredients']}"
)
pdf.ln(35)
pdf.multi_cell(0, 10,
f"πŸ”₯ Calories: {info['calories']} kcal\n"
f"🍞 Carbs: {info['carbs']}g\n"
f"πŸ₯© Protein: {info['protein']}g\n"
f"🧈 Fat: {info['fat']}g"
)
pdf.ln(5)
pdf.multi_cell(0, 10,
f"🌱 Diet Type: {info['diet_type']}\n"
f"πŸ” Substitute: {info.get('substitute', 'None')}"
)
pdf.ln(10)
pdf.set_font("DejaVu", "B", 14)
pdf.cell(0, 10, "Health Analysis", ln=True)
pdf.set_font("DejaVu", size=12)
pdf.multi_cell(0, 10,
f"πŸ“‹ Selected Conditions: {', '.join(conditions)}\n"
f"πŸ“Š Risk Score: {risk_score}% ({risk_level})\n"
f"⚠️ Risk Factors: {', '.join(flags) if flags else 'None'}\n"
f"βœ… Advice: {advice}"
)
pdf.ln(5)
pdf.set_font("DejaVu", "I", 10)
pdf.multi_cell(0, 10, "*Note: This advice is generated using simplified nutritional rules and is not a medical diagnosis.*")
temp_pdf = os.path.join(tempfile.gettempdir(), "report.pdf")
pdf.output(temp_pdf)
return temp_pdf
# Main logic
def classify_food(image, conditions, language):
if not conditions:
return "⚠️ Please select at least one health condition.", None, None, None
image = image.convert("RGB").resize((224, 224))
img_array = tf.keras.preprocessing.image.img_to_array(image) / 255.0
img_array = np.expand_dims(img_array, axis=0)
predictions = model.predict(img_array)[0]
predicted_index = np.argmax(predictions)
predicted_class = class_names[predicted_index]
confidence = round(float(predictions[predicted_index]) * 100, 2)
info = food_info[predicted_class]
display_name = info.get("display_name", predicted_class.title())
advice, risk_score, flags = generate_advice(info, conditions)
risk_level = get_risk_level(risk_score)
# Translate
if language != "English":
try:
translated = GoogleTranslator(source="auto", target=LANG_CODE[language]).translate(advice)
advice = translated
except:
advice += " (⚠️ Translation failed)"
# TTS with fallback
tts_audio = None
try:
tts_lang = LANG_CODE.get(language, "en")
tts = gTTS(text=advice, lang=tts_lang)
tts_audio = os.path.join(tempfile.gettempdir(), "tts.mp3")
tts.save(tts_audio)
except Exception as e:
print(f"TTS error: {e}")
advice += " (⚠️ Voice advice unavailable)"
# Save image and PDF
tmp_img = os.path.join(tempfile.gettempdir(), "upload.jpg")
image.save(tmp_img)
pdf_path = generate_pdf(info, advice, risk_score, risk_level, flags, conditions, language, display_name, tmp_img)
# Output
result = (
f"🧠 *Predictions*:\n"
f"🍲 {display_name} – {confidence}%\n\n"
f"πŸ“‰ *Top Confidence*: {confidence}%\n"
f"πŸ“Š *Risk Score*: {risk_score}% ({risk_level})\n"
f"⚠️ *Risk Factors*: {', '.join(flags) if flags else 'None'}\n"
f"βœ… *Advice*: {advice}\n"
f"πŸ” *Substitute*: {info.get('substitute', 'None')}\n\n"
f"πŸ“ This advice is generated using simple nutrition rules and is not a medical diagnosis."
)
return result, tts_audio, f"πŸ—£οΈ Language: {language}", pdf_path
# Interface
interface = gr.Interface(
fn=classify_food,
inputs=[
gr.Image(type="pil", label="Upload Food Image"),
gr.CheckboxGroup(
label="Select Health Conditions",
choices=["Normal", "Diabetic", "Hypertensive", "Weight Loss", "Malnourished", "Pregnant/Nursing", "Cholesterol Watch"]
),
gr.Dropdown(label="Language for TTS", choices=list(LANG_CODE.keys()), value="English")
],
outputs=[
gr.Textbox(label="Result", lines=10),
gr.Audio(label="Hear Advice"),
gr.Textbox(label="TTS Language"),
gr.File(label="Download Health Report (PDF)")
],
title="πŸ₯— FoodHealth Pro+",
description="Upload a food image. Get full nutrition info, risk score, health advice with voice support in your language and download a detailed PDF."
)
if __name__ == "__main__":
interface.launch()