Building a Streamlit app to identify Indian Food — Part IV (Creating the app and deploying it)

Pradeep Adhokshaja
5 min readNov 12, 2022

--

Streamlit Logo

In the previous post , we looked at fine tuning the EfficientNet-V2 network so that it can classify a food image into one of 85 classes.

Streamlit is an open-source Python-based framework that allows data analysts/ data scientists/ ML Engineers to share their data-related findings in an efficient and succinct manner with the world. This can be done with just a few lines of Python code without using Javascript, CSS, or HTML. You can build dashboards, consumer-facing ML applications, and also a simple website using this library. If you are interested in learning more about this library, you can take a look at a few applications created by the Streamlit Community.

Creating an inference function

Before we go ahead with creating an app, we need to create a function that can accept the image input, process it, and classify it using our trained model. For this application, we present the top 5 classes based on the last layer’s Softmax probability outputs.

The inference function is as follows :

  • From Lines 1 to 8, we import Python libraries that are responsible for invoking the trained model (Tensorflow and Keras), data munging (Pandas), and numerical operations (NumPy).
  • From line 16 onwards, we create a function that takes in the image input and returns the information about the category it belongs to while giving a brief piece of information about its origin and ingredients. The latter information is retrieved from a CSV file that can be found here.
  • For each image, we get the image categories with the top 5 scores, along with their ingredients and places of origin.

Now that we have the inference function ready, we will get into creating a simple web app using the streamlit library.

Creating the streamlit python file

The version of the streamlit library we are using is '1.11.1'.

  • Firstly, we need to import the necessary libraries. The “infer” function is the function for returning the top 5 most probable food image classes, along with their places of origin and their ingredients.
import streamlit as st
import numpy as np
import pandas as pd
#import pydeck as pdk
from PIL import Image
from inference import infer
import time
  • Secondly, we set the page title and page background using the streamlit functions set_page_config() and markdown(). The markdown() function allows one to use CSS commands to resize images and text. In this app, we will set the page title to “Khana Dekho” ( “ Look at the Food” in Hindi/ “See Food” from a prominent HBO comedy series ). The page background is a design template inspired by Indian Restaurants.
st.set_page_config(page_icon="", page_title="Khana Dekho")
def add_bg_from_url():
st.markdown(
f"""
<style>
.stApp {{
background-image: url("https://raw.githubusercontent.com/adhok/SeeFood/main/luxury-ornamental-mandala-design-background_1159-6794.jpg");
background-attachment: fixed;
background-size: cover
}}
</style>
""",
unsafe_allow_html=True
)

add_bg_from_url()
  • Just like any web application we need to include headers to convey what the application is about. As before, we use the markdown() function from the streamlit library to achieve this.
st.markdown("<h1 style='text-align: center; color: orange;'>Khana Dekho (🇮🇳 SeeFood)</h1>", unsafe_allow_html=True)

st.markdown("<h4 style='text-align: center; color: orange;'>A EfficientNetV2 neural network trained to recognize 85 types of Indian Food using the data found <a href = 'https://www.kaggle.com/datasets/iamsouravbanerjee/indian-food-images-dataset'> here. </a> </h4>", unsafe_allow_html=True)

st.markdown("<h4 style='text-align: center; color: orange;'>We present the top five predictions and display their ingredients and region of origin.</h4>", unsafe_allow_html=True)


col1, col2, col3 = st.columns([1,18,1])

  • Finally, we use the streamlit file_uploader() functionality to accept the image input from the user. We also need to make sure that the image has the appropriate extensions (png, jpeg, jpg). We then use the infer() function to get the top 5 food categories, together with their details. Using the markdown() function, we display the top 5 categories with their details.
def load_image(img):
im = Image.open(img)
image = np.array(im)
return image




# Uploading the File to the Page
uploadFile = st.file_uploader(label="Upload image", type=['jpg', 'png','jpeg'])


with col2:



if uploadFile is not None:


img = load_image(uploadFile)


with st.spinner('Wait for it...'):

list_of_predictions,list_of_prep_times,list_of_regions,list_of_ingredients,pred_prob = infer(uploadFile)
st.image(img)
time.sleep(1)





list_of_predictions = [i.replace('_',' ') for i in list_of_predictions]

#st.write('The most likely foods are as follows 👇')

st.markdown("<p style='text-align: center; color: white;'>The most likely foods are as follows 👇.</p>", unsafe_allow_html=True)

if pred_prob[0] > 0.0:


st.markdown("""
#### <p style="color:white">* This is {} . It takes {} minutes to prepare. The cuisine is based in {} India. The ingredients are {} .</p>
""".format(list_of_predictions[0],list_of_prep_times[0],list_of_regions[0],list_of_ingredients[0]), unsafe_allow_html=True)


if pred_prob[1] > 0 :
st.markdown("""
#### <p style="color:white">* This is {} . It takes {} minutes to prepare. The cuisine is based in {} India. The ingredients are {} .</p>
""".format(list_of_predictions[1],list_of_prep_times[1],list_of_regions[1],list_of_ingredients[1]), unsafe_allow_html=True)


if pred_prob[2] > 0:

st.markdown("""
#### <p style="color:white">* This is {} . It takes {} minutes to prepare. The cuisine is based in {} India. The ingredients are {} .</p>
""".format(list_of_predictions[2],list_of_prep_times[2],list_of_regions[2],list_of_ingredients[2]), unsafe_allow_html=True)


if pred_prob[3] > 0:

st.markdown("""
#### <p style="color:white">* This is {} . It takes {} minutes to prepare. The cuisine is based in {} India. The ingredients are {} .</p>
""".format(list_of_predictions[3],list_of_prep_times[3],list_of_regions[3],list_of_ingredients[3]), unsafe_allow_html=True)

# st.write('* This is ',list_of_predictions[3],". It takes ",list_of_prep_times[3],' minutes to prepare.',' The cuisine is based in ',list_of_regions[3], ' India.','The main ingredients are ',list_of_ingredients[3] ,' .')

if pred_prob[4] > 0:

st.markdown("""
#### <p style="color:white">* This is {} . It takes {} minutes to prepare. The cuisine is based in {} India. The ingredients are {} .</p>
""".format(list_of_predictions[4],list_of_prep_times[4],list_of_regions[4],list_of_ingredients[4]), unsafe_allow_html=True)








st.markdown("<p style='text-align: center; color: white;'>Image Uploaded Successfully</p>", unsafe_allow_html=True)
else:

st.markdown("<p style='text-align: center; color: white;'>Make sure you image is in JPG/PNG Format.</p>", unsafe_allow_html=True)

The full code is below

Deploying the app

After pushing your code onto Github, you can create a Streamlit Cloud account here -> https://streamlit.io/cloud

After you create your account, you can click on the New App icon. A new page will open up asking you to share the Github location of your streamlit application( In our case the location of the streamlit_app.py file)

Creating a new application by clicking the “New App” icon
Providing the location of your GitHub repository and streamlit application file(Python File)

The deployment process takes about 15 mins to 20 mins.

The application can be found here -> https://adhok-seefood-streamlit-app-7lw6nk.streamlit.app/

A demo of the application

Final Comments

The application can be made faster by identifying functions in the program that are slow by using a software profiler. The final application can be found here -> https://adhok-seefood-streamlit-app-7lw6nk.streamlit.app/

And thanks for reading! Please feel free to comment below in case of doubts/recommendations and I will do my best to get back to them. You can also email me at padhokshaja@gmail.com

Jian Yang from Silicon Valley (GIPHY)

--

--

Pradeep Adhokshaja
Pradeep Adhokshaja

Written by Pradeep Adhokshaja

Data Scientist @Philips. Passionate about ML,Statistics & hiking. If you like to buy me a coffee, you can use this link https://ko-fi.com/pradeepadhokshaja