Upload 14 files
Browse files- _secret_auth_.json +1 -0
- access_db_admin_panel.bat +1 -0
- db.sqlite3 +0 -0
- hydralit-ver.py +16 -0
- login_ui.py +132 -0
- model_final.h5 +3 -0
- more-testing.py +129 -0
- pb-final-virtualenv-activator.bat +1 -0
- plantbay.py +198 -0
- requirements.txt +152 -0
- run_app.bat +2 -0
- test_user_details.txt +5 -0
- testing.py +64 -0
- utils.py +55 -0
_secret_auth_.json
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
[{"username": "tdfromuk", "name": "Tanuj Dargan", "email": "dargantanuj@gmail.com", "password": "$argon2id$v=19$m=65536,t=3,p=4$yzvra49gzgWatyvdDRyG2A$hhnw/HawxHeEq6+Y4GGRZOOSgtl3gIvLBrEKNayVOpk"}]
|
access_db_admin_panel.bat
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
start "" http://127.0.0.1:8000/admin/
|
db.sqlite3
ADDED
|
Binary file (131 kB). View file
|
|
|
hydralit-ver.py
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#when we import hydralit, we automatically get all of Streamlit
|
| 2 |
+
import hydralit as hy
|
| 3 |
+
|
| 4 |
+
app = hy.HydraApp(title='Simple Multi-Page App')
|
| 5 |
+
|
| 6 |
+
@app.addapp()
|
| 7 |
+
def my_home():
|
| 8 |
+
hy.info('Hello from app1')
|
| 9 |
+
|
| 10 |
+
@app.addapp()
|
| 11 |
+
def app2():
|
| 12 |
+
hy.info('Hello from app 2')
|
| 13 |
+
|
| 14 |
+
|
| 15 |
+
#Run the whole lot, we get navbar, state management and app isolation, all with this tiny amount of work.
|
| 16 |
+
app.run()
|
login_ui.py
ADDED
|
@@ -0,0 +1,132 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import io
|
| 2 |
+
import os
|
| 3 |
+
|
| 4 |
+
import django
|
| 5 |
+
import numpy as np
|
| 6 |
+
import pyrebase
|
| 7 |
+
import streamlit as st
|
| 8 |
+
import tensorflow as tf
|
| 9 |
+
from django.contrib.auth import authenticate
|
| 10 |
+
from django.core.wsgi import get_wsgi_application
|
| 11 |
+
from PIL import Image
|
| 12 |
+
|
| 13 |
+
from utils import clean_image, get_prediction, make_results
|
| 14 |
+
|
| 15 |
+
# Other streamlit imports
|
| 16 |
+
|
| 17 |
+
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'config.settings')
|
| 18 |
+
application = get_wsgi_application()
|
| 19 |
+
|
| 20 |
+
login_btn = st.button('Login')
|
| 21 |
+
|
| 22 |
+
if login_btn:
|
| 23 |
+
import streamlit as st
|
| 24 |
+
from streamlit_login_auth_ui.widgets import __login__
|
| 25 |
+
|
| 26 |
+
__login__obj = __login__(auth_token = "pk_prod_T3JEHHA0FTMDBNHXGENTAXXMXHAC",
|
| 27 |
+
company_name = "Shims",
|
| 28 |
+
width = 200, height = 250,
|
| 29 |
+
logout_button_name = 'Logout', hide_menu_bool = False,
|
| 30 |
+
hide_footer_bool = False,
|
| 31 |
+
lottie_url = 'https://assets2.lottiefiles.com/packages/lf20_jcikwtux.json')
|
| 32 |
+
|
| 33 |
+
LOGGED_IN = __login__obj.build_login_ui()
|
| 34 |
+
|
| 35 |
+
if LOGGED_IN == True:
|
| 36 |
+
st.write('Logged in')
|
| 37 |
+
|
| 38 |
+
else:
|
| 39 |
+
st.markdown("Your Streamlit Application Begins here!")
|
| 40 |
+
# Loading the Model and saving to cache
|
| 41 |
+
@st.cache(allow_output_mutation=True)
|
| 42 |
+
def load_model(path):
|
| 43 |
+
# Xception Model
|
| 44 |
+
xception_model = tf.keras.models.Sequential([
|
| 45 |
+
tf.keras.applications.xception.Xception(include_top=False, weights='imagenet', input_shape=(512, 512, 3)),
|
| 46 |
+
tf.keras.layers.GlobalAveragePooling2D(),
|
| 47 |
+
tf.keras.layers.Dense(4,activation='softmax')
|
| 48 |
+
])
|
| 49 |
+
|
| 50 |
+
|
| 51 |
+
# DenseNet Model
|
| 52 |
+
densenet_model = tf.keras.models.Sequential([
|
| 53 |
+
tf.keras.applications.densenet.DenseNet121(include_top=False, weights='imagenet',input_shape=(512, 512, 3)),
|
| 54 |
+
tf.keras.layers.GlobalAveragePooling2D(),
|
| 55 |
+
tf.keras.layers.Dense(4,activation='softmax')
|
| 56 |
+
])
|
| 57 |
+
|
| 58 |
+
# Ensembling the Models
|
| 59 |
+
inputs = tf.keras.Input(shape=(512, 512, 3))
|
| 60 |
+
|
| 61 |
+
xception_output = xception_model(inputs)
|
| 62 |
+
densenet_output = densenet_model(inputs)
|
| 63 |
+
|
| 64 |
+
outputs = tf.keras.layers.average([densenet_output, xception_output])
|
| 65 |
+
|
| 66 |
+
|
| 67 |
+
model = tf.keras.Model(inputs=inputs, outputs=outputs)
|
| 68 |
+
|
| 69 |
+
# Loading the Weights of Model
|
| 70 |
+
model.load_weights(path)
|
| 71 |
+
|
| 72 |
+
return model
|
| 73 |
+
|
| 74 |
+
|
| 75 |
+
# Removing Menu
|
| 76 |
+
hide_streamlit_style = """
|
| 77 |
+
<style>
|
| 78 |
+
#MainMenu {visibility: hidden;}
|
| 79 |
+
footer {visibility: hidden;}
|
| 80 |
+
</style>
|
| 81 |
+
"""
|
| 82 |
+
st.markdown(hide_streamlit_style, unsafe_allow_html=True)
|
| 83 |
+
|
| 84 |
+
# Title and Description
|
| 85 |
+
st.image('https://raw.githubusercontent.com/tanujdargan/plantbay/main/assets/plantbay.png?token=GHSAT0AAAAAABSBHTQM2WJJ5O7UQFBB2M5MYWPHMCQ')
|
| 86 |
+
st.write('Welcome to PlantBay!', 'Your Personal Plant Assistant!')
|
| 87 |
+
|
| 88 |
+
option = st.selectbox(
|
| 89 |
+
'How would you like to detect a disease?',
|
| 90 |
+
('Camera', 'Upload an Image'))
|
| 91 |
+
if option == 'Camera':
|
| 92 |
+
uploaded_file = st.camera_input("Take a picture")
|
| 93 |
+
if uploaded_file != None:
|
| 94 |
+
st.success('File Upload Success!!')
|
| 95 |
+
elif option == 'Upload an Image':
|
| 96 |
+
uploaded_file = st.file_uploader("Choose a Image file", type=["png", "jpg","jpeg"])
|
| 97 |
+
# Loading the Model
|
| 98 |
+
model = load_model('model_final.h5')
|
| 99 |
+
if model != None:
|
| 100 |
+
st.text("Keras Model Loaded")
|
| 101 |
+
if uploaded_file != None:
|
| 102 |
+
|
| 103 |
+
# Display progress and text
|
| 104 |
+
progress = st.text("Crunching Image")
|
| 105 |
+
my_bar = st.progress(0)
|
| 106 |
+
i = 0
|
| 107 |
+
|
| 108 |
+
# Reading the uploaded image
|
| 109 |
+
image = Image.open(io.BytesIO(uploaded_file.read()))
|
| 110 |
+
st.image(np.array(Image.fromarray(
|
| 111 |
+
np.array(image)).resize((700, 400), Image.ANTIALIAS)), width=None)
|
| 112 |
+
my_bar.progress(i + 40)
|
| 113 |
+
|
| 114 |
+
# Cleaning the image
|
| 115 |
+
image = clean_image(image)
|
| 116 |
+
|
| 117 |
+
# Making the predictions
|
| 118 |
+
predictions, predictions_arr = get_prediction(model, image)
|
| 119 |
+
my_bar.progress(i + 30)
|
| 120 |
+
|
| 121 |
+
# Making the results
|
| 122 |
+
result = make_results(predictions, predictions_arr)
|
| 123 |
+
|
| 124 |
+
# Removing progress bar and text after prediction done
|
| 125 |
+
my_bar.progress(i + 30)
|
| 126 |
+
progress.empty()
|
| 127 |
+
i = 0
|
| 128 |
+
my_bar.empty()
|
| 129 |
+
|
| 130 |
+
# Show the results
|
| 131 |
+
st.subheader(f"The plant{result['status']} with a prediction probability of {result['prediction']}.")
|
| 132 |
+
|
model_final.h5
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:e8adcd3e6bc7a3e6503c96d9f16205ff02f49fc8e5941e857685106eb6e3adcb
|
| 3 |
+
size 336080168
|
more-testing.py
ADDED
|
@@ -0,0 +1,129 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import io
|
| 2 |
+
import os
|
| 3 |
+
|
| 4 |
+
import django
|
| 5 |
+
import numpy as np
|
| 6 |
+
import pyrebase
|
| 7 |
+
import streamlit as st
|
| 8 |
+
import tensorflow as tf
|
| 9 |
+
from PIL import Image
|
| 10 |
+
from streamlit_option_menu import option_menu
|
| 11 |
+
|
| 12 |
+
from utils import clean_image, get_prediction, make_results
|
| 13 |
+
|
| 14 |
+
menu_choice = option_menu(
|
| 15 |
+
menu_title=None, # required
|
| 16 |
+
options=["Home", "Login/Logout", "History"], # required
|
| 17 |
+
icons=["house", "box-arrow-in-right", "clock-history"], # optional
|
| 18 |
+
menu_icon="cast", # optional
|
| 19 |
+
default_index=0, # optional
|
| 20 |
+
orientation="horizontal",
|
| 21 |
+
)
|
| 22 |
+
|
| 23 |
+
if menu_choice == "Home":
|
| 24 |
+
# Loading the Model and saving to cache
|
| 25 |
+
@st.cache(allow_output_mutation=True)
|
| 26 |
+
def load_model(path):
|
| 27 |
+
# Xception Model
|
| 28 |
+
xception_model = tf.keras.models.Sequential([
|
| 29 |
+
tf.keras.applications.xception.Xception(include_top=False, weights='imagenet', input_shape=(512, 512, 3)),
|
| 30 |
+
tf.keras.layers.GlobalAveragePooling2D(),
|
| 31 |
+
tf.keras.layers.Dense(4,activation='softmax')
|
| 32 |
+
])
|
| 33 |
+
|
| 34 |
+
|
| 35 |
+
# DenseNet Model
|
| 36 |
+
densenet_model = tf.keras.models.Sequential([
|
| 37 |
+
tf.keras.applications.densenet.DenseNet121(include_top=False, weights='imagenet',input_shape=(512, 512, 3)),
|
| 38 |
+
tf.keras.layers.GlobalAveragePooling2D(),
|
| 39 |
+
tf.keras.layers.Dense(4,activation='softmax')
|
| 40 |
+
])
|
| 41 |
+
|
| 42 |
+
# Ensembling the Models
|
| 43 |
+
inputs = tf.keras.Input(shape=(512, 512, 3))
|
| 44 |
+
|
| 45 |
+
xception_output = xception_model(inputs)
|
| 46 |
+
densenet_output = densenet_model(inputs)
|
| 47 |
+
|
| 48 |
+
outputs = tf.keras.layers.average([densenet_output, xception_output])
|
| 49 |
+
|
| 50 |
+
|
| 51 |
+
model = tf.keras.Model(inputs=inputs, outputs=outputs)
|
| 52 |
+
|
| 53 |
+
# Loading the Weights of Model
|
| 54 |
+
model.load_weights(path)
|
| 55 |
+
|
| 56 |
+
return model
|
| 57 |
+
|
| 58 |
+
# Title and Description
|
| 59 |
+
st.image('https://raw.githubusercontent.com/tanujdargan/plantbay/main/assets/plantbay.png?token=GHSAT0AAAAAABSBHTQM2WJJ5O7UQFBB2M5MYWPHMCQ', width=550)
|
| 60 |
+
st.write('Welcome to PlantBay!', 'Your Personal Plant Assistant!')
|
| 61 |
+
|
| 62 |
+
option = st.selectbox(
|
| 63 |
+
'How would you like to detect a disease?',
|
| 64 |
+
('Upload an Image', 'Camera'))
|
| 65 |
+
if option == 'Camera':
|
| 66 |
+
uploaded_file = st.camera_input("Take a picture")
|
| 67 |
+
if uploaded_file != None:
|
| 68 |
+
st.success('File Upload Success!!')
|
| 69 |
+
elif option == 'Upload an Image':
|
| 70 |
+
uploaded_file = st.file_uploader("Choose a Image file", type=["png", "jpg","jpeg"])
|
| 71 |
+
# Loading the Model
|
| 72 |
+
model = load_model('model_final.h5')
|
| 73 |
+
if model != None:
|
| 74 |
+
st.text("Keras Model Loaded")
|
| 75 |
+
if uploaded_file != None:
|
| 76 |
+
|
| 77 |
+
# Display progress and text
|
| 78 |
+
progress = st.text("Crunching Image")
|
| 79 |
+
my_bar = st.progress(0)
|
| 80 |
+
i = 0
|
| 81 |
+
|
| 82 |
+
# Reading the uploaded image
|
| 83 |
+
image = Image.open(io.BytesIO(uploaded_file.read()))
|
| 84 |
+
st.image(np.array(Image.fromarray(
|
| 85 |
+
np.array(image)).resize((700, 400), Image.ANTIALIAS)), width=None)
|
| 86 |
+
my_bar.progress(i + 40)
|
| 87 |
+
|
| 88 |
+
# Cleaning the image
|
| 89 |
+
image = clean_image(image)
|
| 90 |
+
|
| 91 |
+
# Making the predictions
|
| 92 |
+
predictions, predictions_arr = get_prediction(model, image)
|
| 93 |
+
my_bar.progress(i + 30)
|
| 94 |
+
|
| 95 |
+
# Making the results
|
| 96 |
+
result = make_results(predictions, predictions_arr)
|
| 97 |
+
|
| 98 |
+
# Removing progress bar and text after prediction done
|
| 99 |
+
my_bar.progress(i + 30)
|
| 100 |
+
progress.empty()
|
| 101 |
+
i = 0
|
| 102 |
+
my_bar.empty()
|
| 103 |
+
|
| 104 |
+
# Show the results
|
| 105 |
+
st.subheader(f"The plant{result['status']} with a prediction probability of {result['prediction']}.")
|
| 106 |
+
|
| 107 |
+
'''if menu_choice == "Login":
|
| 108 |
+
from streamlit_login_auth_ui.widgets import __login__
|
| 109 |
+
|
| 110 |
+
__login__obj = __login__(auth_token = "pk_prod_T3JEHHA0FTMDBNHXGENTAXXMXHAC",
|
| 111 |
+
company_name = "PlantBay",
|
| 112 |
+
width = 200, height = 250,
|
| 113 |
+
logout_button_name = 'Logout', hide_menu_bool = False,
|
| 114 |
+
hide_footer_bool = False,
|
| 115 |
+
lottie_url = 'https://assets2.lottiefiles.com/packages/lf20_jcikwtux.json')
|
| 116 |
+
|
| 117 |
+
LOGGED_IN = __login__obj.build_login_ui()
|
| 118 |
+
|
| 119 |
+
# Removing Menu
|
| 120 |
+
hide_streamlit_style = """
|
| 121 |
+
<style>
|
| 122 |
+
#MainMenu {visibility: hidden;}
|
| 123 |
+
footer {visibility: hidden;}
|
| 124 |
+
</style>
|
| 125 |
+
"""
|
| 126 |
+
st.markdown(hide_streamlit_style, unsafe_allow_html=True)
|
| 127 |
+
|
| 128 |
+
if menu_choice == "History":
|
| 129 |
+
st.write("History")'''
|
pb-final-virtualenv-activator.bat
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
start cmd.exe /k C:\Users\tanuj\Desktop\plantbay-final\pb-final\Scripts\activate
|
plantbay.py
ADDED
|
@@ -0,0 +1,198 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import io
|
| 2 |
+
import os
|
| 3 |
+
from pathlib import Path
|
| 4 |
+
|
| 5 |
+
import django
|
| 6 |
+
import numpy as np
|
| 7 |
+
import pyrebase
|
| 8 |
+
import streamlit as st
|
| 9 |
+
import tensorflow as tf
|
| 10 |
+
#from django.contrib.auth import authenticate
|
| 11 |
+
#from django.core.wsgi import get_wsgi_application
|
| 12 |
+
from PIL import Image
|
| 13 |
+
|
| 14 |
+
from utils import clean_image, get_prediction, make_results
|
| 15 |
+
|
| 16 |
+
|
| 17 |
+
# Loading the Model and saving to cache
|
| 18 |
+
@st.cache(allow_output_mutation=True)
|
| 19 |
+
def load_model(path):
|
| 20 |
+
# Xception Model
|
| 21 |
+
xception_model = tf.keras.models.Sequential([
|
| 22 |
+
tf.keras.applications.xception.Xception(include_top=False, weights='imagenet', input_shape=(512, 512, 3)),
|
| 23 |
+
tf.keras.layers.GlobalAveragePooling2D(),
|
| 24 |
+
tf.keras.layers.Dense(4,activation='softmax')
|
| 25 |
+
])
|
| 26 |
+
|
| 27 |
+
|
| 28 |
+
# DenseNet Model
|
| 29 |
+
densenet_model = tf.keras.models.Sequential([
|
| 30 |
+
tf.keras.applications.densenet.DenseNet121(include_top=False, weights='imagenet',input_shape=(512, 512, 3)),
|
| 31 |
+
tf.keras.layers.GlobalAveragePooling2D(),
|
| 32 |
+
tf.keras.layers.Dense(4,activation='softmax')
|
| 33 |
+
])
|
| 34 |
+
|
| 35 |
+
# Ensembling the Models
|
| 36 |
+
inputs = tf.keras.Input(shape=(512, 512, 3))
|
| 37 |
+
|
| 38 |
+
xception_output = xception_model(inputs)
|
| 39 |
+
densenet_output = densenet_model(inputs)
|
| 40 |
+
|
| 41 |
+
outputs = tf.keras.layers.average([densenet_output, xception_output])
|
| 42 |
+
|
| 43 |
+
|
| 44 |
+
model = tf.keras.Model(inputs=inputs, outputs=outputs)
|
| 45 |
+
|
| 46 |
+
# Loading the Weights of Model
|
| 47 |
+
model.load_weights(path)
|
| 48 |
+
|
| 49 |
+
return model
|
| 50 |
+
|
| 51 |
+
|
| 52 |
+
# Removing Menu
|
| 53 |
+
hide_streamlit_style = """
|
| 54 |
+
<style>
|
| 55 |
+
#MainMenu {visibility: hidden;}
|
| 56 |
+
footer {visibility: hidden;}
|
| 57 |
+
</style>
|
| 58 |
+
"""
|
| 59 |
+
st.markdown(hide_streamlit_style, unsafe_allow_html=True)
|
| 60 |
+
|
| 61 |
+
# Title and Description
|
| 62 |
+
st.image('https://raw.githubusercontent.com/tanujdargan/plantbay/main/assets/plantbay.png?token=GHSAT0AAAAAABSBHTQM2WJJ5O7UQFBB2M5MYWPHMCQ')
|
| 63 |
+
st.write('Welcome to PlantBay!', 'Your Personal Plant Assistant!')
|
| 64 |
+
link = '[Gallery](http://127.0.0.1:8000/)'
|
| 65 |
+
st.markdown(link, unsafe_allow_html=True)
|
| 66 |
+
|
| 67 |
+
option = st.selectbox(
|
| 68 |
+
'How would you like to detect a disease?',
|
| 69 |
+
('Camera', 'Upload an Image'))
|
| 70 |
+
if option == 'Camera':
|
| 71 |
+
uploaded_file = st.camera_input("Take a picture")
|
| 72 |
+
store_file = st.checkbox('Store the file')
|
| 73 |
+
if uploaded_file != None:
|
| 74 |
+
st.success('File Upload Success!!')
|
| 75 |
+
elif option == 'Upload an Image':
|
| 76 |
+
uploaded_file = st.file_uploader("Choose a Image file", type=["png", "jpg","jpeg"])
|
| 77 |
+
store_file = st.checkbox('Store the file')
|
| 78 |
+
# Loading the Model
|
| 79 |
+
model = load_model('model_final.h5')
|
| 80 |
+
if model != None:
|
| 81 |
+
st.text("Keras Model Loaded")
|
| 82 |
+
if uploaded_file != None:
|
| 83 |
+
|
| 84 |
+
# Display progress and text
|
| 85 |
+
progress = st.text("Crunching Image")
|
| 86 |
+
my_bar = st.progress(0)
|
| 87 |
+
i = 0
|
| 88 |
+
# Reading the uploaded image
|
| 89 |
+
if store_file:
|
| 90 |
+
# Save uploaded file to Django database folder.
|
| 91 |
+
save_folder = './Django-photo-app-main/config/media/photo'
|
| 92 |
+
save_path = Path(save_folder, uploaded_file.name)
|
| 93 |
+
with open(save_path, mode='wb') as w:
|
| 94 |
+
w.write(uploaded_file.getvalue())
|
| 95 |
+
|
| 96 |
+
if save_path.exists():
|
| 97 |
+
st.success(f'File {uploaded_file.name} is successfully saved!')
|
| 98 |
+
stored_path = "C:/Users/tanuj/Desktop/PlantBay-final/Django-photo-app-main/config/media/photo/" + uploaded_file.name
|
| 99 |
+
|
| 100 |
+
image = Image.open(io.BytesIO(uploaded_file.read()))
|
| 101 |
+
st.image(np.array(Image.fromarray(
|
| 102 |
+
np.array(image)).resize((700, 400), Image.ANTIALIAS)), width=None)
|
| 103 |
+
my_bar.progress(i + 40)
|
| 104 |
+
|
| 105 |
+
# Cleaning the image
|
| 106 |
+
image = clean_image(image)
|
| 107 |
+
|
| 108 |
+
# Making the predictions
|
| 109 |
+
predictions, predictions_arr = get_prediction(model, image)
|
| 110 |
+
my_bar.progress(i + 30)
|
| 111 |
+
|
| 112 |
+
# Making the results
|
| 113 |
+
result = make_results(predictions, predictions_arr)
|
| 114 |
+
# Removing progress bar and text after prediction done
|
| 115 |
+
my_bar.progress(i + 30)
|
| 116 |
+
progress.empty()
|
| 117 |
+
i = 0
|
| 118 |
+
my_bar.empty()
|
| 119 |
+
|
| 120 |
+
# Show the results
|
| 121 |
+
st.subheader(f"The plant{result['status']} with a prediction probability of {result['prediction']}.")
|
| 122 |
+
if int(predictions_arr) == 0:
|
| 123 |
+
st.write("No remedies are required for this plant. Your plant is healthy!")
|
| 124 |
+
elif int(predictions_arr) == 1:
|
| 125 |
+
st.write("Your plant is infected with various diseases. Contact an expert for further assistance and to prevent further damage.")
|
| 126 |
+
elif int(predictions_arr) == 2:
|
| 127 |
+
st.write("Your plant has a disease called rust. The following remedies can be used to treat this disease:")
|
| 128 |
+
rust_remedies = ['Dust your plants with sulfur early to prevent infection or to keep mild infections from spreading', 'Space your plants properly to encourage good air circulation', 'Avoid wetting the leaves when watering plants', 'There are many effective rust fungicides you can try. Ask your local nursery for which products you should use in your area']
|
| 129 |
+
for i in rust_remedies:
|
| 130 |
+
st.markdown("- " + i)
|
| 131 |
+
elif int(predictions_arr) == 3:
|
| 132 |
+
st.write("Your plant has a disease called scabbing. The following remedies can be used to treat this disease:")
|
| 133 |
+
scabbing_remedies = ['Gather under the trees and destroy the infected leaves','Watering the plants in the evening or early morning hours and avoiding over-irrigation give the leaves less time to dry out before infection can occur.', 'Spreading a three to a six-inch layer of compost under trees by keeping it away from the trunk and by covering the soil', 'Using a fungicide to treat the trees can help prevent the disease from spreading']
|
| 134 |
+
for i in scabbing_remedies:
|
| 135 |
+
st.markdown("- " + i)
|
| 136 |
+
#saving report as pdf
|
| 137 |
+
report_text1 = "Your plant"+result['status']
|
| 138 |
+
report_text2 = "Prediction accuracy level:"+result['prediction']
|
| 139 |
+
report_text3 = ""
|
| 140 |
+
remedy = False
|
| 141 |
+
remedy2 = False
|
| 142 |
+
if int(predictions_arr) == 0:
|
| 143 |
+
report_text3 = "No remedies are required for this plant. Your plant is healthy!"
|
| 144 |
+
elif int(predictions_arr) == 1:
|
| 145 |
+
report_text3 = "Your plant is infected with various diseases. Contact an expert for further assistance and to prevent further damage."
|
| 146 |
+
elif int(predictions_arr) == 2:
|
| 147 |
+
report_text3 = "Your plant has a disease called rust. The following remedies can be used to treat this disease:"
|
| 148 |
+
report_text4 = 'The following remedies can be used to treat this disease:'
|
| 149 |
+
remedy = True
|
| 150 |
+
elif int(predictions_arr) == 3:
|
| 151 |
+
report_text3 = 'Your plant has a disease called scabbing'
|
| 152 |
+
report_text4 = 'The following remedies can be used to treat this disease:'
|
| 153 |
+
remedy2 = True
|
| 154 |
+
|
| 155 |
+
|
| 156 |
+
import base64
|
| 157 |
+
|
| 158 |
+
import streamlit as st
|
| 159 |
+
from fpdf import FPDF
|
| 160 |
+
|
| 161 |
+
export_as_pdf = st.button("Export Report")
|
| 162 |
+
|
| 163 |
+
def create_download_link(val, filename):
|
| 164 |
+
b64 = base64.b64encode(val) # val looks like b'...'
|
| 165 |
+
return f'<a href="data:application/octet-stream;base64,{b64.decode()}" download="{filename}.pdf">Download file</a>'
|
| 166 |
+
|
| 167 |
+
if export_as_pdf:
|
| 168 |
+
pdf = FPDF()
|
| 169 |
+
pdf.add_page(orientation='L')
|
| 170 |
+
pdf.set_font('Times', 'B', 12)
|
| 171 |
+
pdf.cell(200, 10, txt = report_text1,
|
| 172 |
+
ln = 1, align = 'L')
|
| 173 |
+
pdf.cell(200, 10, txt = report_text2,
|
| 174 |
+
ln = 2, align = 'L')
|
| 175 |
+
pdf.cell(200, 10, txt = report_text3,
|
| 176 |
+
ln = 3, align = 'L')
|
| 177 |
+
pdf.image(stored_path, x = 10, y = 100, w = 100, h = 100)
|
| 178 |
+
if remedy == True:
|
| 179 |
+
pdf.cell(200, 10, txt = report_text4,
|
| 180 |
+
ln = 4, align = 'L')
|
| 181 |
+
count = 0
|
| 182 |
+
for i in rust_remedies:
|
| 183 |
+
pdf.cell(200,10 , txt = rust_remedies[count],
|
| 184 |
+
ln=count, align = 'L')
|
| 185 |
+
count+=1
|
| 186 |
+
elif remedy2 == True:
|
| 187 |
+
count=0
|
| 188 |
+
pdf.cell(200, 10, txt = report_text4,
|
| 189 |
+
ln = 4, align = 'L')
|
| 190 |
+
for i in scabbing_remedies:
|
| 191 |
+
pdf.cell(200,10 , txt = scabbing_remedies[count],
|
| 192 |
+
ln=count, align = 'L')
|
| 193 |
+
count+=1
|
| 194 |
+
|
| 195 |
+
|
| 196 |
+
html = create_download_link(pdf.output(dest="S").encode("latin-1"), "PlantBay_Report")
|
| 197 |
+
|
| 198 |
+
st.markdown(html, unsafe_allow_html=True)
|
requirements.txt
ADDED
|
@@ -0,0 +1,152 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
absl-py==1.3.0
|
| 2 |
+
altair==4.2.0
|
| 3 |
+
argon2-cffi==21.3.0
|
| 4 |
+
argon2-cffi-bindings==21.2.0
|
| 5 |
+
asgiref==3.5.2
|
| 6 |
+
astunparse==1.6.3
|
| 7 |
+
async-generator==1.10
|
| 8 |
+
attrs==22.1.0
|
| 9 |
+
beautifulsoup4==4.11.1
|
| 10 |
+
blinker==1.5
|
| 11 |
+
bokeh==3.0.2
|
| 12 |
+
bs4==0.0.1
|
| 13 |
+
cachetools==5.2.0
|
| 14 |
+
certifi==2022.9.24
|
| 15 |
+
cffi==1.15.1
|
| 16 |
+
charset-normalizer==2.1.1
|
| 17 |
+
click==8.1.3
|
| 18 |
+
colorama==0.4.6
|
| 19 |
+
commonmark==0.9.1
|
| 20 |
+
compress-pickle==2.1.0
|
| 21 |
+
contourpy==1.0.6
|
| 22 |
+
cryptography==38.0.3
|
| 23 |
+
cycler==0.11.0
|
| 24 |
+
decorator==5.1.1
|
| 25 |
+
Deprecated==1.2.13
|
| 26 |
+
Django==4.1.3
|
| 27 |
+
django-appconf==1.0.5
|
| 28 |
+
django-crispy-forms==1.14.0
|
| 29 |
+
django-imagekit==4.1.0
|
| 30 |
+
django-resized==1.0.2
|
| 31 |
+
django-starcross-gallery==1.0.14
|
| 32 |
+
django-taggit==3.1.0
|
| 33 |
+
entrypoints==0.4
|
| 34 |
+
exceptiongroup==1.0.4
|
| 35 |
+
extra-streamlit-components==0.1.56
|
| 36 |
+
Faker==15.3.3
|
| 37 |
+
favicon==0.7.0
|
| 38 |
+
flatbuffers==22.10.26
|
| 39 |
+
fonttools==4.38.0
|
| 40 |
+
gast==0.4.0
|
| 41 |
+
gcloud==0.18.3
|
| 42 |
+
gitdb==4.0.9
|
| 43 |
+
GitPython==3.1.29
|
| 44 |
+
google-auth==2.14.1
|
| 45 |
+
google-auth-oauthlib==0.4.6
|
| 46 |
+
google-pasta==0.2.0
|
| 47 |
+
googleapis-common-protos==1.57.0
|
| 48 |
+
grpcio==1.50.0
|
| 49 |
+
h11==0.14.0
|
| 50 |
+
h5py==3.7.0
|
| 51 |
+
htbuilder==0.6.1
|
| 52 |
+
httplib2==0.21.0
|
| 53 |
+
hydralit==1.0.14
|
| 54 |
+
hydralit-components==1.0.10
|
| 55 |
+
idna==3.4
|
| 56 |
+
importlib-metadata==5.0.0
|
| 57 |
+
Jinja2==3.1.2
|
| 58 |
+
jsonschema==4.17.0
|
| 59 |
+
jwcrypto==1.4.2
|
| 60 |
+
keras==2.11.0
|
| 61 |
+
kiwisolver==1.4.4
|
| 62 |
+
libclang==14.0.6
|
| 63 |
+
lxml==4.9.1
|
| 64 |
+
Markdown==3.4.1
|
| 65 |
+
markdownlit==0.0.5
|
| 66 |
+
MarkupSafe==2.1.1
|
| 67 |
+
matplotlib==3.6.2
|
| 68 |
+
more-itertools==9.0.0
|
| 69 |
+
numpy==1.23.5
|
| 70 |
+
oauth2client==4.1.3
|
| 71 |
+
oauthlib==3.2.2
|
| 72 |
+
opencv-python==4.6.0.66
|
| 73 |
+
opt-einsum==3.3.0
|
| 74 |
+
outcome==1.2.0
|
| 75 |
+
packaging==21.3
|
| 76 |
+
pandas==1.5.1
|
| 77 |
+
pilkit==2.0
|
| 78 |
+
Pillow==9.1.1
|
| 79 |
+
protobuf==3.19.6
|
| 80 |
+
psycopg2==2.9.5
|
| 81 |
+
psycopg2-binary==2.9.1
|
| 82 |
+
pyarrow==10.0.0
|
| 83 |
+
pyasn1==0.4.8
|
| 84 |
+
pyasn1-modules==0.2.8
|
| 85 |
+
pycparser==2.21
|
| 86 |
+
pycryptodome==3.15.0
|
| 87 |
+
pydeck==0.8.0
|
| 88 |
+
Pygments==2.13.0
|
| 89 |
+
pymdown-extensions==9.8
|
| 90 |
+
Pympler==1.0.1
|
| 91 |
+
pyparsing==3.0.9
|
| 92 |
+
Pyrebase4==4.5.0
|
| 93 |
+
pyrsistent==0.19.2
|
| 94 |
+
PySocks==1.7.1
|
| 95 |
+
python-dateutil==2.8.2
|
| 96 |
+
python-jwt==4.0.0
|
| 97 |
+
pytz==2021.1
|
| 98 |
+
pytz-deprecation-shim==0.1.0.post0
|
| 99 |
+
PyYAML==6.0
|
| 100 |
+
requests==2.28.1
|
| 101 |
+
requests-oauthlib==1.3.1
|
| 102 |
+
requests-toolbelt==0.10.1
|
| 103 |
+
rich==12.6.0
|
| 104 |
+
rsa==4.9
|
| 105 |
+
selenium==4.7.2
|
| 106 |
+
semver==2.13.0
|
| 107 |
+
simple-photo-gallery==1.5.4
|
| 108 |
+
six==1.16.0
|
| 109 |
+
smmap==5.0.0
|
| 110 |
+
sniffio==1.3.0
|
| 111 |
+
sortedcontainers==2.4.0
|
| 112 |
+
soupsieve==2.3.2.post1
|
| 113 |
+
sqlparse==0.4.1
|
| 114 |
+
st-annotated-text==3.0.0
|
| 115 |
+
st-btn-select==0.1.2
|
| 116 |
+
streamlit==1.15.1
|
| 117 |
+
streamlit-camera-input-live==0.2.0
|
| 118 |
+
streamlit-cookies-manager==0.2.0
|
| 119 |
+
streamlit-embedcode==0.1.2
|
| 120 |
+
streamlit-extras==0.2.3
|
| 121 |
+
streamlit-faker==0.0.2
|
| 122 |
+
streamlit-keyup==0.2.0
|
| 123 |
+
streamlit-login-auth-ui==0.2.0
|
| 124 |
+
streamlit-lottie==0.0.3
|
| 125 |
+
streamlit-option-menu==0.3.2
|
| 126 |
+
streamlit-toggle-switch==1.0.2
|
| 127 |
+
streamlit-vertical-slider==1.0.2
|
| 128 |
+
tensorboard==2.11.0
|
| 129 |
+
tensorboard-data-server==0.6.1
|
| 130 |
+
tensorboard-plugin-wit==1.8.1
|
| 131 |
+
tensorflow==2.11.0
|
| 132 |
+
tensorflow-estimator==2.11.0
|
| 133 |
+
tensorflow-intel==2.11.0
|
| 134 |
+
tensorflow-io-gcs-filesystem==0.27.0
|
| 135 |
+
termcolor==2.1.1
|
| 136 |
+
toml==0.10.2
|
| 137 |
+
toolz==0.12.0
|
| 138 |
+
tornado==6.2
|
| 139 |
+
trio==0.22.0
|
| 140 |
+
trio-websocket==0.9.2
|
| 141 |
+
trycourier==4.4.0
|
| 142 |
+
typing_extensions==4.4.0
|
| 143 |
+
tzdata==2022.6
|
| 144 |
+
tzlocal==4.2
|
| 145 |
+
urllib3==1.26.12
|
| 146 |
+
validators==0.20.0
|
| 147 |
+
watchdog==2.1.9
|
| 148 |
+
Werkzeug==2.2.2
|
| 149 |
+
wrapt==1.14.1
|
| 150 |
+
wsproto==1.2.0
|
| 151 |
+
xyzservices==2022.9.0
|
| 152 |
+
zipp==3.10.0
|
run_app.bat
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
|
|
|
|
|
|
|
| 1 |
+
start cmd /k "cd /d C:\Users\tanuj\Desktop\plantbay-final\pb-final\Scripts & activate & cd /d C:\Users\tanuj\Desktop\plantbay-final\Django-photo-app-main\config & python manage.py runserver"
|
| 2 |
+
start cmd /k "cd /d C:\Users\tanuj\Desktop\plantbay-final & streamlit run plantbay.py"
|
test_user_details.txt
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
username: testuser1
|
| 2 |
+
password: pwd_test1
|
| 3 |
+
|
| 4 |
+
username: testuser2
|
| 5 |
+
password: pwd_test2
|
testing.py
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import streamlit as st
|
| 2 |
+
from streamlit_option_menu import option_menu
|
| 3 |
+
|
| 4 |
+
# 1=sidebar menu, 2=horizontal menu, 3=horizontal menu w/ custom menu
|
| 5 |
+
EXAMPLE_NO = 2
|
| 6 |
+
|
| 7 |
+
|
| 8 |
+
def streamlit_menu(example=1):
|
| 9 |
+
if example == 1:
|
| 10 |
+
# 1. as sidebar menu
|
| 11 |
+
with st.sidebar:
|
| 12 |
+
selected = option_menu(
|
| 13 |
+
menu_title="Main Menu", # required
|
| 14 |
+
options=["Home", "Projects", "Contact"], # required
|
| 15 |
+
icons=["house", "book", "envelope"], # optional
|
| 16 |
+
menu_icon="cast", # optional
|
| 17 |
+
default_index=0, # optional
|
| 18 |
+
)
|
| 19 |
+
return selected
|
| 20 |
+
|
| 21 |
+
if example == 2:
|
| 22 |
+
# 2. horizontal menu w/o custom style
|
| 23 |
+
selected = option_menu(
|
| 24 |
+
menu_title=None, # required
|
| 25 |
+
options=["Home", "Projects", "Contact"], # required
|
| 26 |
+
icons=["house", "book", "envelope"], # optional
|
| 27 |
+
menu_icon="cast", # optional
|
| 28 |
+
default_index=0, # optional
|
| 29 |
+
orientation="horizontal",
|
| 30 |
+
)
|
| 31 |
+
return selected
|
| 32 |
+
|
| 33 |
+
if example == 3:
|
| 34 |
+
# 2. horizontal menu with custom style
|
| 35 |
+
selected = option_menu(
|
| 36 |
+
menu_title=None, # required
|
| 37 |
+
options=["Home", "Projects", "Contact"], # required
|
| 38 |
+
icons=["house", "book", "envelope"], # optional
|
| 39 |
+
menu_icon="cast", # optional
|
| 40 |
+
default_index=0, # optional
|
| 41 |
+
orientation="horizontal",
|
| 42 |
+
styles={
|
| 43 |
+
"container": {"padding": "0!important", "background-color": "#fafafa"},
|
| 44 |
+
"icon": {"color": "orange", "font-size": "25px"},
|
| 45 |
+
"nav-link": {
|
| 46 |
+
"font-size": "25px",
|
| 47 |
+
"text-align": "left",
|
| 48 |
+
"margin": "0px",
|
| 49 |
+
"--hover-color": "#eee",
|
| 50 |
+
},
|
| 51 |
+
"nav-link-selected": {"background-color": "green"},
|
| 52 |
+
},
|
| 53 |
+
)
|
| 54 |
+
return selected
|
| 55 |
+
|
| 56 |
+
|
| 57 |
+
selected = streamlit_menu(example=EXAMPLE_NO)
|
| 58 |
+
|
| 59 |
+
if selected == "Home":
|
| 60 |
+
st.title(f"You have selected {selected}")
|
| 61 |
+
if selected == "Projects":
|
| 62 |
+
st.title(f"You have selected {selected}")
|
| 63 |
+
if selected == "Contact":
|
| 64 |
+
st.title(f"You have selected {selected}")
|
utils.py
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Imporiting Necessary Libraries
|
| 2 |
+
import numpy as np
|
| 3 |
+
import tensorflow as tf
|
| 4 |
+
from PIL import Image
|
| 5 |
+
|
| 6 |
+
|
| 7 |
+
# Cleaning image
|
| 8 |
+
def clean_image(image):
|
| 9 |
+
image = np.array(image)
|
| 10 |
+
|
| 11 |
+
# Resizing the image
|
| 12 |
+
image = np.array(Image.fromarray(
|
| 13 |
+
image).resize((512, 512), Image.ANTIALIAS))
|
| 14 |
+
|
| 15 |
+
# Adding batch dimensions to the image
|
| 16 |
+
# YOu are seeting :3, that's becuase sometimes users upload 4 channel image,
|
| 17 |
+
image = image[np.newaxis, :, :, :3]
|
| 18 |
+
# So we just take first 3 channels
|
| 19 |
+
|
| 20 |
+
return image
|
| 21 |
+
|
| 22 |
+
|
| 23 |
+
def get_prediction(model, image):
|
| 24 |
+
|
| 25 |
+
datagen = tf.keras.preprocessing.image.ImageDataGenerator(
|
| 26 |
+
rescale=1./255)
|
| 27 |
+
|
| 28 |
+
# Inputting the image to keras generators
|
| 29 |
+
test = datagen.flow(image)
|
| 30 |
+
|
| 31 |
+
# Predict from the image
|
| 32 |
+
predictions = model.predict(test)
|
| 33 |
+
predictions_arr = np.array(np.argmax(predictions))
|
| 34 |
+
|
| 35 |
+
return predictions, predictions_arr
|
| 36 |
+
|
| 37 |
+
|
| 38 |
+
# Making the final results
|
| 39 |
+
def make_results(predictions, predictions_arr):
|
| 40 |
+
|
| 41 |
+
result = {}
|
| 42 |
+
if int(predictions_arr) == 0:
|
| 43 |
+
result = {"status": " is Healthy ",
|
| 44 |
+
"prediction": f"{int(predictions[0][0].round(2)*100)}%"}
|
| 45 |
+
if int(predictions_arr) == 1:
|
| 46 |
+
result = {"status": ' has Multiple Diseases ',
|
| 47 |
+
"prediction": f"{int(predictions[0][1].round(2)*100)}%"}
|
| 48 |
+
if int(predictions_arr) == 2:
|
| 49 |
+
result = {"status": ' has Rusting ',
|
| 50 |
+
"prediction": f"{int(predictions[0][2].round(2)*100)}%"}
|
| 51 |
+
if int(predictions_arr) == 3:
|
| 52 |
+
result = {"status": ' has Scabbing ',
|
| 53 |
+
"prediction": f"{int(predictions[0][3].round(2)*100)}%"}
|
| 54 |
+
return result
|
| 55 |
+
|