Spaces:
Running
Running
Upload app.py
Browse files
app.py
ADDED
@@ -0,0 +1,142 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import json
|
2 |
+
from PIL import Image
|
3 |
+
import os
|
4 |
+
|
5 |
+
import streamlit as st
|
6 |
+
import pandas as pd
|
7 |
+
import numpy as np
|
8 |
+
|
9 |
+
import tensorflow as tf
|
10 |
+
import tensorflow_hub as hub
|
11 |
+
from tensorflow.keras.utils import img_to_array, load_img
|
12 |
+
|
13 |
+
|
14 |
+
@st.cache(allow_output_mutation=True)
|
15 |
+
def load_model(path='models/inceptionV3_model'):
|
16 |
+
"""Retrieves the trained model and maps it to the CPU by default,
|
17 |
+
can also specify GPU here."""
|
18 |
+
model = tf.keras.Sequential([hub.KerasLayer(path)])
|
19 |
+
model.build([None, 224, 224, 3])
|
20 |
+
return model
|
21 |
+
|
22 |
+
|
23 |
+
@st.cache()
|
24 |
+
def load_index_to_label_dict(
|
25 |
+
path: str = 'index_to_class_label.json'
|
26 |
+
) -> dict:
|
27 |
+
"""Retrieves and formats the
|
28 |
+
index to class label
|
29 |
+
lookup dictionary needed to
|
30 |
+
make sense of the predictions.
|
31 |
+
When loaded in, the keys are strings, this also
|
32 |
+
processes those keys to integers."""
|
33 |
+
with open(path, 'r') as f:
|
34 |
+
index_to_class_label_dict = json.load(f)
|
35 |
+
index_to_class_label_dict = {
|
36 |
+
int(k): v for k, v in index_to_class_label_dict.items()}
|
37 |
+
return index_to_class_label_dict
|
38 |
+
|
39 |
+
|
40 |
+
def load_files(
|
41 |
+
keys: list,
|
42 |
+
path: str = 'images'
|
43 |
+
) -> list:
|
44 |
+
"""Retrieves files from images folder"""
|
45 |
+
files = []
|
46 |
+
for file in os.listdir(path):
|
47 |
+
files.append(Image.open(path + '/' + file))
|
48 |
+
return files
|
49 |
+
|
50 |
+
|
51 |
+
def load_image(
|
52 |
+
filename: str = '0.jpg',
|
53 |
+
path: str = 'images'
|
54 |
+
) -> list:
|
55 |
+
"""return image with path and filename"""
|
56 |
+
return Image.open(path + '/' + filename)
|
57 |
+
|
58 |
+
|
59 |
+
@st.cache(ttl=24*3600)
|
60 |
+
def predict(
|
61 |
+
img: Image.Image,
|
62 |
+
index_to_label_dict: dict,
|
63 |
+
model,
|
64 |
+
k: int
|
65 |
+
) -> list:
|
66 |
+
"""
|
67 |
+
This function transforms the image accordingly,
|
68 |
+
puts it to the necessary device (cpu by default here),
|
69 |
+
feeds the image through the model getting the output tensor,
|
70 |
+
converts that output tensor to probabilities using Softmax,
|
71 |
+
and then extracts and formats the top k predictions.
|
72 |
+
"""
|
73 |
+
img = img.resize((224, 224))
|
74 |
+
image = img_to_array(img)
|
75 |
+
image = np.expand_dims(image, axis=0)
|
76 |
+
preds = model.predict(image)
|
77 |
+
formatted_predictions = list()
|
78 |
+
for idx, x in zip(range(0,6), preds[0]):
|
79 |
+
formatted_predictions.append([index_to_class_label_dict[idx], np.round(x*100,3)])
|
80 |
+
formatted_predictions = sorted(formatted_predictions, key=lambda x:(x[1]), reverse=True)
|
81 |
+
return formatted_predictions
|
82 |
+
|
83 |
+
|
84 |
+
if __name__ == '__main__':
|
85 |
+
model = load_model()
|
86 |
+
index_to_class_label_dict = load_index_to_label_dict()
|
87 |
+
|
88 |
+
st.title('Rate My Photo!')
|
89 |
+
instructions = """
|
90 |
+
Either upload your own image or select from
|
91 |
+
the sidebar to get a preconfigured image.
|
92 |
+
The image you select or upload will be fed
|
93 |
+
through the Deep Neural Network in real-time
|
94 |
+
and the output will be displayed to the screen.
|
95 |
+
"""
|
96 |
+
st.write(instructions)
|
97 |
+
|
98 |
+
file = st.file_uploader('Upload An Image')
|
99 |
+
images_type = {
|
100 |
+
'Bright': '0.jpg',
|
101 |
+
'Dark': '1.jpg',
|
102 |
+
'Good': '2.jpg',
|
103 |
+
'Lens Flare': '3.jpg',
|
104 |
+
'Loss': '4.jpg',
|
105 |
+
'Motion Blur': '5.jpg'
|
106 |
+
}
|
107 |
+
data_split_names = list(images_type.keys())
|
108 |
+
|
109 |
+
if file: # if user uploaded file
|
110 |
+
img = Image.open(file)
|
111 |
+
prediction = predict(img, index_to_class_label_dict, model, k=5)
|
112 |
+
|
113 |
+
else:
|
114 |
+
image_type = st.sidebar.selectbox("Examples", data_split_names)
|
115 |
+
image_file = images_type[image_type]
|
116 |
+
|
117 |
+
example_images = load_files(keys=images_type)
|
118 |
+
img = load_image(image_file)
|
119 |
+
prediction = predict(img, index_to_class_label_dict, model, 5)
|
120 |
+
|
121 |
+
st.title("Here is the image you've selected")
|
122 |
+
resized_image = img.resize((336, 336))
|
123 |
+
st.image(resized_image)
|
124 |
+
if prediction[0][0] == "Good":
|
125 |
+
text = "good"
|
126 |
+
else:
|
127 |
+
text = "bad"
|
128 |
+
st.title("Your photo is in " + text + " quality")
|
129 |
+
st.title("Here are the five most likely reasons why")
|
130 |
+
df = pd.DataFrame(data=np.zeros((5, 2)),
|
131 |
+
columns=['Reason', 'Confidence Level'],
|
132 |
+
index=np.linspace(1, 5, 5, dtype=int))
|
133 |
+
|
134 |
+
for idx, p in enumerate(prediction[:5]):
|
135 |
+
df.iloc[idx, 0] = p[0]
|
136 |
+
df.iloc[idx, 1] = str(p[1]) + '%'
|
137 |
+
st.write(df.to_html(escape=False), unsafe_allow_html=True)
|
138 |
+
st.write('\n')
|
139 |
+
credits = """
|
140 |
+
This project was developed by <a href="https://www.linkedin.com/in/eran-perelman/" style="text-decoration: none">Eran Perelman</a>, <a href="https://www.linkedin.com/in/asi-sheratzki/" style="text-decoration: none">Asi Sheratzki</a> and <a href="https://www.linkedin.com/in/arykorenvais/" style="text-decoration: none">Ary Korenvais</a> with the guidance of <a href="https://www.linkedin.com/in/morris-alper/" style="text-decoration: none">Morris Alper</a>.
|
141 |
+
"""
|
142 |
+
st.write(credits, unsafe_allow_html=True)
|