Spaces:
Sleeping
Sleeping
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   </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:  ' + 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 + '"') | |