|
|
import gradio as gr |
|
|
import tensorflow as tf |
|
|
import numpy as np |
|
|
from PIL import Image |
|
|
import json |
|
|
from datetime import datetime |
|
|
import tempfile |
|
|
import os |
|
|
from gtts import gTTS |
|
|
from fpdf import FPDF |
|
|
from health_logic import generate_advice |
|
|
from tensorflow.keras.applications.efficientnet import preprocess_input as efficientnet_preprocess |
|
|
|
|
|
|
|
|
model = tf.keras.models.load_model("food_vision_model.keras") |
|
|
|
|
|
|
|
|
class_names = [ |
|
|
"akara", "banga_soup", "egusi_soup", "jollof_rice", "moi_moi", |
|
|
"nkwobi", "okpa", "suya", "tuwo", "yam_porridge" |
|
|
] |
|
|
|
|
|
|
|
|
with open("food_info.json", "r") as f: |
|
|
food_info = json.load(f) |
|
|
|
|
|
|
|
|
LANG_CODE = { |
|
|
"English": "en", |
|
|
"Hausa": "en", |
|
|
"Yoruba": "en", |
|
|
"Igbo": "en" |
|
|
} |
|
|
|
|
|
|
|
|
def get_risk_level(score): |
|
|
if score <= 30: |
|
|
return "π’ Low Risk" |
|
|
elif score <= 70: |
|
|
return "π‘ Medium Risk" |
|
|
else: |
|
|
return "π΄ High Risk" |
|
|
|
|
|
|
|
|
class UnicodePDF(FPDF): |
|
|
def header(self): |
|
|
self.set_font("DejaVu", "B", 16) |
|
|
self.cell(0, 10, "HoodHealth Pro+ Report", ln=True) |
|
|
|
|
|
def footer(self): |
|
|
self.set_y(-15) |
|
|
self.set_font("DejaVu", "I", 8) |
|
|
self.cell(0, 10, f"Generated: {datetime.now().strftime('%Y-%m-%d %H:%M')}", align="C") |
|
|
|
|
|
def generate_pdf(info, advice, risk_score, risk_level, flags, conditions, lang, display_name, image_path): |
|
|
pdf = UnicodePDF() |
|
|
pdf.add_font("DejaVu", "", "DejaVuSans.ttf", uni=True) |
|
|
pdf.add_font("DejaVu", "B", "DejaVuSans.ttf", uni=True) |
|
|
pdf.add_font("DejaVu", "I", "DejaVuSans.ttf", uni=True) |
|
|
pdf.add_page() |
|
|
pdf.set_font("DejaVu", "", 12) |
|
|
|
|
|
pdf.image(image_path, x=10, y=40, w=60) |
|
|
pdf.set_xy(75, 40) |
|
|
pdf.multi_cell(0, 10, f"Food: {display_name}\nEthnicity: {info['ethnicity']}\nIngredients: {info['ingredients']}") |
|
|
|
|
|
pdf.ln(35) |
|
|
pdf.multi_cell(0, 10, f"Calories: {info['calories']} kcal\nCarbs: {info['carbs']}g\nProtein: {info['protein']}g\nFat: {info['fat']}g") |
|
|
pdf.ln(5) |
|
|
pdf.multi_cell(0, 10, f"Diet Type: {info['diet_type']}\nSubstitute: {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", "", 12) |
|
|
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}") |
|
|
pdf.ln(5) |
|
|
pdf.set_font("DejaVu", "I", 10) |
|
|
pdf.multi_cell(0, 10, "*Note: This advice is not a medical diagnosis.*") |
|
|
|
|
|
path = os.path.join(tempfile.gettempdir(), "report.pdf") |
|
|
pdf.output(path) |
|
|
return path |
|
|
|
|
|
def classify_food(image): |
|
|
try: |
|
|
|
|
|
image = image.convert("L").resize((225, 225)) |
|
|
img = tf.keras.preprocessing.image.img_to_array(image) |
|
|
|
|
|
|
|
|
if img.shape[-1] != 1: |
|
|
img = np.expand_dims(img, axis=-1) |
|
|
|
|
|
|
|
|
img = efficientnet_preprocess(img) |
|
|
img = np.expand_dims(img, axis=0) |
|
|
|
|
|
|
|
|
preds = model.predict(img) |
|
|
pred_class = np.argmax(preds[0]) |
|
|
confidence = float(np.max(preds[0])) |
|
|
|
|
|
food_name = class_names[pred_class] |
|
|
food_details = food_info[food_name] |
|
|
|
|
|
result = f"π½οΈ Food: {food_name}\n" |
|
|
result += f"π Ethnicity: {food_details['Ethnicity']}\n" |
|
|
result += f"π₯¦ Ingredients: {', '.join(food_details['Ingredients'])}\n" |
|
|
result += f"π₯ Nutrients: {food_details['Nutrients']}\n" |
|
|
result += f"β€οΈ Health Advice: {food_details['Health_Advice']}\n" |
|
|
result += f"π± Diet Type: {food_details['Diet_Type']}\n" |
|
|
result += f"π Confidence: {confidence:.2f}" |
|
|
|
|
|
return result |
|
|
|
|
|
except Exception as e: |
|
|
return f"Error during classification: {str(e)}" |
|
|
|
|
|
|
|
|
|
|
|
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=["English", "Hausa", "Yoruba", "Igbo"], value="English") |
|
|
], |
|
|
outputs=[ |
|
|
gr.Textbox(label="Prediction and Advice"), |
|
|
gr.Audio(label="Hear Advice"), |
|
|
gr.Textbox(label="Language Info"), |
|
|
gr.File(label="Download PDF Report") |
|
|
], |
|
|
title="π² HoodHealth Pro+", |
|
|
description="Upload a food image and get nutrition details, health risk, personalized advice, audio guidance, and a downloadable PDF report." |
|
|
) |
|
|
|
|
|
if __name__ == "__main__": |
|
|
interface.launch() |
|
|
|