Spaces:
Sleeping
Sleeping
Commit
·
bb1ba0d
1
Parent(s):
4c2b597
Upload 4 files
Browse files
app.py
ADDED
@@ -0,0 +1,98 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# Imporiting Necessary Libraries
|
2 |
+
import streamlit as st
|
3 |
+
from PIL import Image
|
4 |
+
import io
|
5 |
+
import numpy as np
|
6 |
+
import tensorflow as tf
|
7 |
+
from utils import clean_image, get_prediction, make_results
|
8 |
+
|
9 |
+
# Loading the Model and saving to cache
|
10 |
+
@st.cache(allow_output_mutation=True)
|
11 |
+
def load_model(path):
|
12 |
+
|
13 |
+
# Xception Model
|
14 |
+
xception_model = tf.keras.models.Sequential([
|
15 |
+
tf.keras.applications.xception.Xception(include_top=False, weights='imagenet', input_shape=(512, 512, 3)),
|
16 |
+
tf.keras.layers.GlobalAveragePooling2D(),
|
17 |
+
tf.keras.layers.Dense(4,activation='softmax')
|
18 |
+
])
|
19 |
+
|
20 |
+
|
21 |
+
# DenseNet Model
|
22 |
+
densenet_model = tf.keras.models.Sequential([
|
23 |
+
tf.keras.applications.densenet.DenseNet121(include_top=False, weights='imagenet',input_shape=(512, 512, 3)),
|
24 |
+
tf.keras.layers.GlobalAveragePooling2D(),
|
25 |
+
tf.keras.layers.Dense(4,activation='softmax')
|
26 |
+
])
|
27 |
+
|
28 |
+
# Ensembling the Models
|
29 |
+
inputs = tf.keras.Input(shape=(512, 512, 3))
|
30 |
+
|
31 |
+
xception_output = xception_model(inputs)
|
32 |
+
densenet_output = densenet_model(inputs)
|
33 |
+
|
34 |
+
outputs = tf.keras.layers.average([densenet_output, xception_output])
|
35 |
+
|
36 |
+
|
37 |
+
model = tf.keras.Model(inputs=inputs, outputs=outputs)
|
38 |
+
|
39 |
+
# Loading the Weights of Model
|
40 |
+
model.load_weights(path)
|
41 |
+
|
42 |
+
return model
|
43 |
+
|
44 |
+
|
45 |
+
# Removing Menu
|
46 |
+
hide_streamlit_style = """
|
47 |
+
<style>
|
48 |
+
#MainMenu {visibility: hidden;}
|
49 |
+
footer {visibility: hidden;}
|
50 |
+
</style>
|
51 |
+
"""
|
52 |
+
st.markdown(hide_streamlit_style, unsafe_allow_html=True)
|
53 |
+
|
54 |
+
# Loading the Model
|
55 |
+
model = load_model('model.h5')
|
56 |
+
|
57 |
+
# Title and Description
|
58 |
+
st.title('Plant Diesease Detection')
|
59 |
+
st.write("Just Upload your Plant's Leaf Image and get predictions if the plant is healthy or not")
|
60 |
+
|
61 |
+
# Setting the files that can be uploaded
|
62 |
+
uploaded_file = st.file_uploader("Choose a Image file", type=["png", "jpg"])
|
63 |
+
|
64 |
+
# If there is a uploaded file, start making prediction
|
65 |
+
if uploaded_file != None:
|
66 |
+
|
67 |
+
# Display progress and text
|
68 |
+
progress = st.text("Crunching Image")
|
69 |
+
my_bar = st.progress(0)
|
70 |
+
i = 0
|
71 |
+
|
72 |
+
# Reading the uploaded image
|
73 |
+
image = Image.open(io.BytesIO(uploaded_file.read()))
|
74 |
+
st.image(np.array(Image.fromarray(
|
75 |
+
np.array(image)).resize((700, 400), Image.ANTIALIAS)), width=None)
|
76 |
+
my_bar.progress(i + 40)
|
77 |
+
|
78 |
+
# Cleaning the image
|
79 |
+
image = clean_image(image)
|
80 |
+
|
81 |
+
# Making the predictions
|
82 |
+
predictions, predictions_arr = get_prediction(model, image)
|
83 |
+
my_bar.progress(i + 30)
|
84 |
+
|
85 |
+
# Making the results
|
86 |
+
result = make_results(predictions, predictions_arr)
|
87 |
+
|
88 |
+
# Removing progress bar and text after prediction done
|
89 |
+
my_bar.progress(i + 30)
|
90 |
+
progress.empty()
|
91 |
+
i = 0
|
92 |
+
my_bar.empty()
|
93 |
+
|
94 |
+
# Show the results
|
95 |
+
st.write(f"The plant {result['status']} with {result['prediction']} prediction.")
|
96 |
+
|
97 |
+
|
98 |
+
|
model.h5
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:e8640ee5f4430338106102c031d535efdb1e5f0cf5bb52d7ba89eec7ad4f9f65
|
3 |
+
size 336021776
|
requirements.txt
ADDED
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
tensorflow
|
2 |
+
streamlit
|
3 |
+
Pillow==9.5.0
|
4 |
+
numpy
|
5 |
+
scipy
|
utils.py
ADDED
@@ -0,0 +1,54 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# Imporiting Necessary Libraries
|
2 |
+
import tensorflow as tf
|
3 |
+
import numpy as np
|
4 |
+
from PIL import Image
|
5 |
+
|
6 |
+
|
7 |
+
# Cleanig 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 user 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 Rust ',
|
50 |
+
"prediction": f"{int(predictions[0][2].round(2)*100)}%"}
|
51 |
+
if int(predictions_arr) == 3:
|
52 |
+
result = {"status": ' has Scab ',
|
53 |
+
"prediction": f"{int(predictions[0][3].round(2)*100)}%"}
|
54 |
+
return result
|