File size: 6,516 Bytes
9cbc26e
cd57e36
9cbc26e
a72a046
9cbc26e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
64b163b
9cbc26e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
a72a046
9cbc26e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
a72a046
 
 
9cbc26e
8c4836d
a72a046
 
9cbc26e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
a72a046
 
 
cd57e36
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151

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 + '"')