Stavros Niafas commited on
Commit
630886e
1 Parent(s): ff0981e

update bokeh space

Browse files
app.py ADDED
@@ -0,0 +1,58 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Streamlit web app for depth of field detection"""
2
+
3
+ import time
4
+ from PIL import Image
5
+ import streamlit as st
6
+ from bokeh import app_dof_predict
7
+
8
+ from tempfile import NamedTemporaryFile
9
+
10
+ temp_file = NamedTemporaryFile(delete=False)
11
+
12
+ # Page layout
13
+ st.set_page_config(page_title="Depth of Field Detection", page_icon=":camera:", layout="wide")
14
+
15
+ # Sidebar options
16
+ st.sidebar.title("Prediction Settings")
17
+ st.sidebar.text("")
18
+
19
+ models = ["DenseNet (baseline)", "VGG16 (baseline)", "DenseNet (best)", "VGG16 (best)"]
20
+
21
+ model_choice = []
22
+ st.sidebar.write("Choose a model for prediction")
23
+ model_choice.append(st.sidebar.radio("", models))
24
+
25
+ with st.container():
26
+ st.title("Depth of Field detection w/ Deep Learning")
27
+ st.image(
28
+ "https://source.unsplash.com/FABH5NJEMGM/960x640",
29
+ use_column_width="auto",
30
+ )
31
+
32
+ file = st.file_uploader("Upload an image", type=["jpg", "jpeg"])
33
+
34
+ if file is not None:
35
+ img = Image.open(file)
36
+ temp_file.write(file.getvalue())
37
+ st.image(img, caption="Uploaded image", use_column_width="auto")
38
+
39
+ if st.button("Predict"):
40
+ st.write("")
41
+ st.write("Working...")
42
+
43
+ start_time = time.time()
44
+
45
+ for choice in model_choice:
46
+ prediction = app_dof_predict(choice, temp_file.name)
47
+ print(prediction)
48
+ execute_bar = st.progress(0)
49
+ for percent_complete in range(100):
50
+ time.sleep(0.001)
51
+ execute_bar.progress(percent_complete + 1)
52
+ prob = prediction["probability"]
53
+ if prediction["class"] == 0:
54
+ st.header("Prediction: Bokeh - Confidence {:.1f}%".format(prob * 100))
55
+ elif prediction["class"] == 1:
56
+ st.header("Prediction: No bokeh detected - Confidence {:.1f}%".format(prob * 100))
57
+
58
+ st.write("Took {} seconds to run.".format(round(time.time() - start_time, 2)))
bokeh.py ADDED
@@ -0,0 +1,184 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import argparse
2
+ import json
3
+ import gdown
4
+ import os
5
+ import matplotlib.pyplot as plt
6
+ import numpy as np
7
+ import streamlit as st
8
+
9
+ from pathlib import Path
10
+
11
+ os.environ["TF_CPP_MIN_LOG_LEVEL"] = "2"
12
+ os.environ["CUDA_VISIBLE_DEVICES"] = "-1"
13
+
14
+ import tensorflow as tf
15
+ from tensorflow.keras.models import load_model
16
+
17
+
18
+ @st.cache(show_spinner=False)
19
+ def download_weights(model_choice):
20
+ """
21
+ Downloads model weights for deployment
22
+ """
23
+
24
+ # Create directory
25
+ save_dest = Path("models")
26
+ save_dest.mkdir(exist_ok=True)
27
+
28
+ # Download weights for the chosen model
29
+ if model_choice == "DenseNet (baseline)":
30
+ url = "https://drive.google.com/uc?id=10-TWkCW_BAZLpGXkxPqXFV8lg-jnWNJD"
31
+ output = "models/densenet.h5"
32
+
33
+ if not Path(output).exists():
34
+ with st.spinner("Model weights were not found, downloading them. This may take a while."):
35
+ gdown.download(url, output, quiet=False)
36
+
37
+ elif model_choice == "VGG16 (baseline)":
38
+ url = "https://drive.google.com/uc?id=1UaNIHQ-HYeN5v6egV9kAdwU0Nb4CfLBF"
39
+ output = "models/vgg16.h5"
40
+
41
+ if not Path(output).exists():
42
+ with st.spinner("Model weights were not found, downloading them. This may take a while."):
43
+ gdown.download(url, output, quiet=False)
44
+
45
+ elif model_choice == "DenseNet (best)":
46
+ url = "https://drive.google.com/uc?id=1JUvuzyGQpScHyq2q25yhG962g3PMJ1eu"
47
+ output = "models/densenet_best.h5"
48
+
49
+ if not Path(output).exists():
50
+ with st.spinner("Model weights were not found, downloading them. This may take a while."):
51
+ gdown.download(url, output, quiet=False)
52
+
53
+ elif model_choice == "VGG16 (best)":
54
+ url = "https://drive.google.com/uc?id=19iu-Qhaofczgl6iMt6DSB_OHDBs9ggsr"
55
+ output = "models/vgg16_best.h5"
56
+
57
+ if not Path(output).exists():
58
+ with st.spinner("Model weights were not found, downloading them. This may take a while."):
59
+ gdown.download(url, output, quiet=False)
60
+ else:
61
+ raise ValueError("Unknown model: {}".format(model_choice))
62
+
63
+
64
+ def preprocess_image(image_file):
65
+ """Preprocess image"""
66
+
67
+ x, _ = process_path(image_file)
68
+ x = np.expand_dims(x, axis=0)
69
+
70
+ return x
71
+
72
+
73
+ def app_dof_predict(model_choice, image_file):
74
+
75
+ # Download weights for the chosen model
76
+ download_weights(model_choice)
77
+ image = preprocess_image(image_file)
78
+ prediction = {}
79
+
80
+ if model_choice == "DenseNet (baseline)":
81
+ model = load_model("models/densenet.h5", compile=False)
82
+ elif model_choice == "VGG16 (baseline)":
83
+ model = load_model("models/vgg16.h5", compile=False)
84
+ elif model_choice == "DenseNet (best)":
85
+ model = load_model("models/densenet_best.h5", compile=False)
86
+ elif model_choice == "VGG16 (best)":
87
+ model = load_model("models/vgg16_best.h5", compile=False)
88
+ preds = model.predict(image)
89
+
90
+ prediction = {
91
+ "class": int(np.argmax(preds)),
92
+ "probability": float(preds[0][np.argmax(preds)]),
93
+ }
94
+
95
+ return prediction
96
+
97
+
98
+ def decode_img(img):
99
+ """Decode image and resize"""
100
+ img = tf.image.decode_jpeg(img, channels=3)
101
+ img = tf.image.resize(img, [200, 300])
102
+
103
+ return img
104
+
105
+
106
+ def process_path(file_path):
107
+ """Process input path"""
108
+ img = tf.io.read_file(file_path)
109
+ img = decode_img(img)
110
+
111
+ return img, file_path
112
+
113
+
114
+ def plot_results(infer_images, inference_predicted_class, inference_predictions, class_names=["bokeh", "no bokeh"]):
115
+ """Plot four images with predicted class and probabilities"""
116
+ plt.figure(figsize=(40, 60))
117
+
118
+ for i, (infer_img, _) in enumerate(infer_images.take(10)):
119
+ ax = plt.subplot(2, 5, i + 1)
120
+ plt.imshow(infer_img.numpy() / 255)
121
+
122
+ # Find the predicted class from predictions
123
+
124
+ m = "Predicted: {}, {:.2f}%".format(class_names[inference_predicted_class[i]], inference_predictions[i] * 100)
125
+ plt.title(m)
126
+ plt.axis("off")
127
+ plt.show()
128
+
129
+
130
+ def dof_predict(infer_images, model_path):
131
+
132
+ trained_model = load_model(model_path, compile=False)
133
+
134
+ inference_predicted_class = []
135
+ inference_predictions = []
136
+ results = {}
137
+ for infer_img, img_name in infer_images:
138
+ print(img_name)
139
+ preds = trained_model.predict(tf.expand_dims(infer_img, axis=0))
140
+ inference_predicted_class.append(np.argmax(preds))
141
+ print(preds)
142
+ inference_predictions.append(preds[0][np.argmax(preds)])
143
+
144
+ results[str(img_name.numpy().decode("utf8").split("/")[-1])] = {
145
+ "class": int(np.argmax(preds)),
146
+ "prob": float(preds[0][np.argmax(preds)]),
147
+ }
148
+
149
+ plot_results(infer_images, inference_predicted_class, inference_predictions)
150
+
151
+ return results
152
+
153
+
154
+ def save_results(results):
155
+ """Save results to json"""
156
+ json.dump(results, open("results.json", "w"))
157
+
158
+
159
+ def main(test_dir, model_path):
160
+
161
+ # get the count of image files in the train directory
162
+ inference_ds = tf.data.Dataset.list_files(test_dir + "/*", shuffle=False)
163
+
164
+ infer_images = inference_ds.map(process_path)
165
+
166
+ # inference
167
+ results = dof_predict(infer_images, model_path)
168
+
169
+ # save results
170
+ save_results(results)
171
+
172
+
173
+ if __name__ == "__main__":
174
+
175
+ # Initiate the parser
176
+ parser = argparse.ArgumentParser()
177
+
178
+ parser.add_argument("-data", action="store", help="Dataset path")
179
+ parser.add_argument("-model", action="store", help="Model path")
180
+ arguments = parser.parse_args()
181
+
182
+ dataset = arguments.data
183
+ model = arguments.model
184
+ main(dataset, model)
media/-3LtGq_RPcY.jpg ADDED
media/AS2KB6jD1SU.jpg ADDED
media/XRwDE7DnDbg.jpg ADDED
media/xR3hdMS3Imw.jpg ADDED
requirements.txt ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ tensorflow=2.3.1
2
+ numpy=1.18.5
3
+ gdown=4.2.0
4
+ pillow=*