WhatTheFood / app.py
prithivida's picture
Updated scale
d7bb99b
import streamlit as st
import streamlit.components.v1 as components
from PIL import Image
import os
import glob
import random
from random import shuffle
import requests
import time
from multiprocessing import Process
import json
def load_image(image_file):
img = Image.open(image_file)
return img
def start_server():
os.system("uvicorn InferenceServer:app --port 8080 --host 0.0.0.0 --workers 3")
def load_models():
if not is_port_in_use(8080):
with st.spinner(text="Loading models, please wait..."):
proc = Process(target=start_server, args=(), daemon=True)
proc.start()
while not is_port_in_use(8080):
time.sleep(1)
st.success("Model server started.")
else:
st.success("Model server already running...")
st.session_state['models_loaded'] = True
def is_port_in_use(port):
import socket
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
return s.connect_ex(('0.0.0.0', port)) == 0
def run_search(food_image):
get_request = "http://0.0.0.0:8080/food?food_input="+food_image
food_response = requests.get(get_request)
food_response_obj = json.loads(food_response.text)
results = food_response_obj["top3"]
st.markdown("<br/>", unsafe_allow_html=True)
with col2:
st.markdown("<b>Top 3 predictions &nbsp </b>", unsafe_allow_html=True)
results_static_tag = '<html><title>W3.CSS</title><meta name="viewport" content="width=device-width, initial-scale=1"><link rel="stylesheet" href="https://www.w3schools.com/w3css/4/w3.css"><body><div class="w3-container">{}</div></body></html>'
result_rows = ""
for i, result in enumerate(results):
results_dynamic_tag= '{} <br/> <div class="w3-light-grey"> <div class="{}" style="height:4px;width:{}%"></div> </div><br>'
if i == 0:
results_dynamic_tag = results_dynamic_tag.format("<b>" + str(i+1) + "." + result[0].title() + "</b>", 'w3-blue', result[1] * 100)
else:
results_dynamic_tag = results_dynamic_tag.format(str(i+1) + "." + result[0].title(), "w3-orange" ,result[1] * 100)
result_rows += results_dynamic_tag
results_static_tag = results_static_tag.format(result_rows)
st.markdown(results_static_tag, unsafe_allow_html=True)
recipe_response_obj = food_response_obj["recipe"]
recipe_name = recipe_response_obj['recipe_name']
highlighted_ingredients =recipe_response_obj['highlighted_ingredients']
recipe = recipe_response_obj['recipe']
source = recipe_response_obj['source']
nutritional_facts = recipe_response_obj['nutritional_facts']
title_tag = '<h4> Recipe for top result: &nbsp' + recipe_name + '</h4>'
st.markdown(title_tag, unsafe_allow_html=True)
ing_hdr_tag = '<h5> Ingredients </h5>'
ing_style= "{border: 3x outset white; background-color: #ccf5ff; color: black; text-align: left; font-size: 14px; padding: 5px;}"
ing_tag = '<html><head><style>.ingdiv{}</style></head><body><div class="ingdiv">{}</div></body></html>'
ing_tag = ing_tag.format(ing_style, highlighted_ingredients.strip())
st.markdown(ing_hdr_tag, unsafe_allow_html=True)
st.markdown(ing_tag + "<br/>", unsafe_allow_html=True)
rec_hdr_tag = '<h5> Recipe </h5>'
rec_style= "{border: 3x outset white; background-color: #ffeee6; color: black; text-align: left; font-size: 14px; padding: 5px;}"
rec_tag = '<html><head><style>.recdiv{}</style></head><body><div class="recdiv">{}</div></body></html>'
rec_tag = rec_tag.format(rec_style, recipe.strip())
st.markdown(rec_hdr_tag, unsafe_allow_html=True)
st.markdown(rec_tag + "<br/>", unsafe_allow_html=True)
nut_hdr_tag = '<h5> Nutritional facts </h5>'
nut_style= "{border: 3x outset white; background-color: #e6e6ff; color: black; text-align: left; font-size: 14px; padding: 5px;}"
nut_tag = '<html><head><style>.nutdiv{}</style></head><body><div class="nutdiv">{}</div></body></html>'
nut_tag = nut_tag.format(nut_style, nutritional_facts.strip())
st.markdown(nut_hdr_tag, unsafe_allow_html=True)
st.markdown(nut_tag + "<br/>", unsafe_allow_html=True)
src_hdr_tag = '<h5> Recipe source </h5>'
src_tag = '<a href={} target="_blank">{}</a>'
src_tag = src_tag.format(source, source)
st.markdown(src_hdr_tag, unsafe_allow_html=True)
st.markdown(src_tag + "<br/>", unsafe_allow_html=True)
return 1
if 'models_loaded' not in st.session_state:
st.session_state['models_loaded'] = False
st.title('WTF - What The Food 🀬')
st.subheader("Image to Recipe - 1.5M foods supported")
st.markdown("Built for fun with πŸ’™ by a quintessential foodie - Prithivi Da, The maker of [Gramformer](https://github.com/PrithivirajDamodaran/Gramformer), [Styleformer](https://github.com/PrithivirajDamodaran/Styleformer) and [Parrot paraphraser](https://github.com/PrithivirajDamodaran/Parrot_Paraphraser) | ✍️ [@prithivida](https://twitter.com/prithivida) |[[GitHub]](https://github.com/PrithivirajDamodaran)", unsafe_allow_html=True)
st.markdown("""<i> (Read Me: The idea: Food Image => Recipe. So it works on single foods and platters <p style='color:red; display:inline'> but May Not perform well on custom combinations or hyper-local foods. (NOT intended for commercial use.) </p>) </i>""", unsafe_allow_html=True)
if __name__ == '__main__':
if not st.session_state['models_loaded']:
load_models()
random_button = st.button('⚑ Try a Random Food')
st.write("(or)")
st.info('Upload a HD, landscape image')
image_file = st.file_uploader("", type=["jpg","jpeg"])
col1, col2 = st.columns(2)
if random_button:
with st.spinner(text="Detecting food..."):
samples = glob.glob('./samples' + "/*")
shuffle(samples)
random_sample = random.choice(samples)
pil_image = load_image(random_sample)
with col1:
st.image(pil_image, use_column_width='auto')
return_code = run_search(random_sample)
else:
if image_file is not None:
pil_image = load_image(image_file)
with open(image_file.name, 'wb') as f:
pil_image.save(f)
with col1:
st.image(pil_image, use_column_width='auto')
with st.spinner(text="Detecting food..."):
return_code = run_search(image_file.name)
os.system('rm -r "' + image_file.name + '"')