SakshiRathi77 commited on
Commit
ebdd126
1 Parent(s): 526103f

Upload app (1).py

Browse files
Files changed (1) hide show
  1. app (1).py +296 -0
app (1).py ADDED
@@ -0,0 +1,296 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # https://planogram-compliance.herokuapp.com/
2
+ # https://dashboard.heroku.com/apps/planogram-compliance/deploy/heroku-git
3
+
4
+ # https://medium.com/@mohcufe/how-to-deploy-your-trained-pytorch-model-on-heroku-ff4b73085ddd\
5
+ # https://stackoverflow.com/questions/51730880/where-do-i-get-a-cpu-only-version-of-pytorch
6
+ # https://blog.jcharistech.com/2020/02/26/how-to-deploy-a-face-detection-streamlit-app-on-heroku/
7
+ # https://towardsdatascience.com/a-quick-tutorial-on-how-to-deploy-your-streamlit-app-to-heroku-
8
+ # https://www.analyticsvidhya.com/blog/2021/06/deploy-your-ml-dl-streamlit-application-on-heroku/
9
+ # https://gist.github.com/jeremyjordan/6b506257509e8ba673f145baa568a1ea
10
+
11
+ import json
12
+
13
+ # https://www.r-bloggers.com/2020/12/creating-a-streamlit-web-app-building-with-docker-github-actions-and-hosting-on-heroku/
14
+ # https://devcenter.heroku.com/articles/container-registry-and-runtime
15
+ # from yolo_inference_util import run_yolo_v5
16
+ import os
17
+ from tempfile import NamedTemporaryFile
18
+
19
+ import cv2
20
+ import numpy as np
21
+ import pandas as pd
22
+ import streamlit as st
23
+
24
+ # import matplotlib.pyplot as plt
25
+ from app_utils import annotate_planogram_compliance, bucket_sort, do_sorting, xml_to_csv
26
+ from inference import run
27
+
28
+ # from utils.plots import Annotator, colors
29
+ # from utils.general import scale_coords
30
+
31
+ app_formal_name = "Planogram Compliance"
32
+
33
+ FILE_UPLOAD_DIR = "tmp"
34
+
35
+ os.makedirs(FILE_UPLOAD_DIR, exist_ok=True)
36
+ # Start the app in wide-mode
37
+ st.set_page_config(
38
+ layout="wide",
39
+ page_title=app_formal_name,
40
+ )
41
+ # https://github.com/streamlit/streamlit/issues/1361
42
+ uploaded_file = st.file_uploader(
43
+ "Choose a planogram image to score",
44
+ type=["jpg", "JPEG", "PNG", "JPG", "jpeg"],
45
+ )
46
+ uploaded_master_planogram_file = st.file_uploader(
47
+ "Upload a master planogram", type=["jpg", "JPEG", "PNG", "JPG", "jpeg"]
48
+ )
49
+ annotation_file = st.file_uploader("upload master polanogram", type=["xml"])
50
+ temp_file = NamedTemporaryFile(delete=False)
51
+
52
+ target_names = [
53
+ "Bottle,100PLUS ACTIVE 1.5L",
54
+ "Bottle,100PLUS ACTIVE 500ML",
55
+ "Bottle,100PLUS LEMON LIME 1.5L",
56
+ "Bottle,100PLUS ORANGE 500ML",
57
+ "Bottle,100PLUS ORIGINAL 1.5L",
58
+ "Bottle,100PLUS TANGY ORANGE 1.5L",
59
+ "Bottle,100PLUS ZERO 1.5L",
60
+ "Bottle,100PLUS ZERO 500ML",
61
+ "Packet,F:M MAGNOLIA CHOC 1L",
62
+ "Bottle,F&N GINGER ADE 1.5L",
63
+ "Bottle,F&N GRAPE 1.5L",
64
+ "Bottle,F&N ICE CREAM SODA 1.5L",
65
+ "Bottle,F&N LYCHEE PEAR 1.5L",
66
+ "Bottle,F&N ORANGE 1.5L",
67
+ "Bottle,F&N PINEAPPLE PET 1.5L",
68
+ "Bottle,F&N SARSI 1.5L",
69
+ "Bottle,F&N SS ICE LEM TEA RS 500ML",
70
+ "Bottle,F&N SS ICE LEMON TEA RS 1.5L",
71
+ "Bottle,F&N SS ICE LEMON TEA 1.5L",
72
+ "Bottle,F&N SS ICE LEMON TEA 500ML",
73
+ "Bottle,F&N SS ICE PEACH TEA 1.5L",
74
+ "Bottle,SS ICE LEMON GT 1.48L",
75
+ "Bottle,SS WHITE CHRYS TEA 1.48L",
76
+ "Packet,FARMHOUSE FRESH MILK 1L FNDM",
77
+ "Packet,FARMHOUSE PLAIN LF 1L",
78
+ "Packet,PURA FRESH MILK 1L FS",
79
+ "Packet,NUTRISOY REG NO SUGAR ADDED 1L",
80
+ "Packet,NUTRISOY PLAIN 475ML",
81
+ "Packet,NUTRISOY PLAIN 1L",
82
+ "Packet,NUTRISOY OMEGA RD SUGAR 1L",
83
+ "Packet,NUTRISOY OMEGA NSA 1L",
84
+ "Packet,NUTRISOY ALMOND 1L",
85
+ "Packet,MAGNOLIA FRESH MILK 1L FNDM",
86
+ "Packet,FM MAG FC PLAIN 200ML",
87
+ "Packet,MAG OMEGA PLUS PLAIN 200ML",
88
+ "Packet,MAG KURMA MILK 500ML",
89
+ "Packet,MAG KURMA MILK 1L",
90
+ "Packet,MAG CHOCOLATE FC 500ML",
91
+ "Packet,MAG BROWN SUGAR SS MILK 1L",
92
+ "Packet,FM MAG LFHC PLN 500ML",
93
+ "Packet,FM MAG LFHC OAT 500ML",
94
+ "Packet,FM MAG LFHC OAT 1L",
95
+ "Packet,FM MAG FC PLAIN 500ML",
96
+ "Void,PARTIAL VOID",
97
+ "Void,FULL VOID",
98
+ "Bottle,F&N SS ICE LEM TEA 500ML",
99
+ ]
100
+
101
+ run_app = st.button("Run the compliance check")
102
+ if run_app and uploaded_file is not None:
103
+ # Convert the file to an opencv image.
104
+ file_bytes = np.asarray(bytearray(uploaded_file.read()), dtype=np.uint8)
105
+ temp_file.write(uploaded_file.getvalue())
106
+ uploaded_img = cv2.imdecode(file_bytes, 1)
107
+ cv2.imwrite("tmp/to_score_planogram_tmp.png", uploaded_img)
108
+
109
+ # if uploaded_master_planogram_file is None:
110
+ # master = cv2.imread('./sample_master_planogram.jpeg')
111
+
112
+ names_dict = {name: id for id, name in enumerate(target_names)}
113
+
114
+ sorted_xml_df = None
115
+ # https://discuss.streamlit.io/t/unable-to-read-files-using-standard-file-uploader/2258/2
116
+ if uploaded_master_planogram_file and annotation_file:
117
+ file_bytes = np.asarray(
118
+ bytearray(uploaded_master_planogram_file.read()), dtype=np.uint8
119
+ )
120
+ master = cv2.imdecode(file_bytes, 1)
121
+ cv2.imwrite("tmp/master_tmp.png", master)
122
+ # cv2.imwrite("tmp_uploaded_master_planogram_img.png", master)
123
+ # xml = annotation_file.read()
124
+ # tmp_xml ="tmp_xml_annotation.xml"
125
+ # with open(tmp_xml ,'w',encoding='utf-8') as f:
126
+ # xml = f.write(xml)
127
+ xml_df = xml_to_csv(annotation_file)
128
+ xml_df["cls"] = xml_df["cls"].map(names_dict)
129
+ sorted_xml_df = do_sorting(xml_df)
130
+ sorted_xml_df.line_number.value_counts()
131
+
132
+ line_data = sorted_xml_df.line_number.value_counts()
133
+ n_rows = int(len(line_data))
134
+ n_cols = int(max(line_data))
135
+ master_table = np.zeros((n_rows, n_cols)) + 101
136
+ master_annotations = []
137
+ for i, row in sorted_xml_df.groupby("line_number"):
138
+ # print(f"Adding products in the row {i} to the detected planogram", row.cls.tolist())
139
+ products = row.cls.tolist()
140
+ master_table[int(i - 1), 0 : len(products)] = products
141
+ annotations = [
142
+ (int(k), int(v))
143
+ for k, v in list(
144
+ zip(row.cls.unique(), row.cls.value_counts().tolist())
145
+ )
146
+ ]
147
+ master_annotations.append(annotations)
148
+ master_table.shape
149
+ # print("Annoatated planogram")
150
+ # print(np.matrix(master_table))
151
+
152
+ elif uploaded_master_planogram_file:
153
+ print(
154
+ "Finding the amster annotations with the YOLOv5 model predictions"
155
+ )
156
+ file_bytes = np.asarray(
157
+ bytearray(uploaded_master_planogram_file.read()), dtype=np.uint8
158
+ )
159
+ master = cv2.imdecode(file_bytes, 1)
160
+ cv2.imwrite("tmp/master_tmp.png", master)
161
+ master_results = run(
162
+ weights="base_line_best_model_exp5.pt",
163
+ source="tmp/master_tmp.png",
164
+ imgsz=[640, 640],
165
+ conf_thres=0.6,
166
+ iou_thres=0.6,
167
+ )
168
+
169
+ bb_df = pd.DataFrame(
170
+ master_results[0][1].tolist(),
171
+ columns=["xmin", "ymin", "xmax", "ymax", "conf", "cls"],
172
+ )
173
+ sorted_df = do_sorting(bb_df)
174
+
175
+ n_rows = int(sorted_df.line_number.max())
176
+ n_cols = int(
177
+ sorted_df.groupby("line_number")
178
+ .size()
179
+ .reset_index(name="counts")["counts"]
180
+ .max()
181
+ )
182
+ non_null_product = 101
183
+ print("master size", n_rows, n_cols)
184
+ master_annotations = []
185
+ master_table = np.zeros((int(n_rows), int(n_cols))) + non_null_product
186
+ for i, row in sorted_df.groupby("line_number"):
187
+ # print(f"Adding products in the row {i} to the detected planogram", row.cls.tolist())
188
+ products = row.cls.tolist()
189
+ col_len = min(len(products), n_cols)
190
+ print("col size: ", col_len)
191
+ print("row size: ", i - 1)
192
+ if n_rows <= (i - 1):
193
+ print("more rows than expected in the predictions")
194
+ break
195
+ master_table[int(i - 1), 0:col_len] = products[:col_len]
196
+ annotations = [
197
+ (int(k), int(v))
198
+ for k, v in list(
199
+ zip(row.cls.unique(), row.cls.value_counts().tolist())
200
+ )
201
+ ]
202
+ master_annotations.append(annotations)
203
+ else:
204
+ master = cv2.imread("./sample_master_planogram.jpeg")
205
+ n_rows = 3
206
+ n_cols = 16
207
+ master_table = np.zeros((n_rows, n_cols)) + 101
208
+ master_annotations = [
209
+ [(32, 12), (8, 4)],
210
+ [(36, 1), (41, 6), (50, 4), (51, 3), (52, 2)],
211
+ [(23, 5), (24, 6), (54, 5)],
212
+ ]
213
+
214
+ for i, row in enumerate(master_annotations):
215
+ idx = 0
216
+ for product, count in row:
217
+ master_table[i, idx : idx + count] = product
218
+ idx = idx + count
219
+ # Now do something with the image! For example, let's display it:
220
+ # st.image(opencv_image, channels="BGR")
221
+
222
+ # uploaded_img = '/content/drive/My Drive/0.CV/0.Planogram_Compliance/planogram_data/images/test/IMG_5718.jpg'
223
+ result_list = run(
224
+ weights="base_line_best_model_exp5.pt",
225
+ source="tmp/to_score_planogram_tmp.png",
226
+ imgsz=[640, 640],
227
+ conf_thres=0.6,
228
+ iou_thres=0.6,
229
+ )
230
+
231
+ bb_df = pd.DataFrame(
232
+ result_list[0][1].tolist(),
233
+ columns=["xmin", "ymin", "xmax", "ymax", "conf", "cls"],
234
+ )
235
+ sorted_df = do_sorting(bb_df)
236
+
237
+ non_null_product = 101
238
+ print("master size", n_rows, n_cols)
239
+ detected_table = np.zeros((n_rows, n_cols)) + non_null_product
240
+ for i, row in sorted_df.groupby("line_number"):
241
+ # print(f"Adding products in the row {i} to the detected planogram", row.cls.tolist())
242
+ products = row.cls.tolist()
243
+ col_len = min(len(products), n_cols)
244
+ print("col size: ", col_len)
245
+ print("row size: ", i - 1)
246
+ if n_rows <= (i - 1):
247
+ print("more rows than expected in the predictions")
248
+ break
249
+ detected_table[int(i - 1), 0:col_len] = products[:col_len]
250
+
251
+ # score = (master_table == detected_table).sum() / (master_table != non_null_product).sum()
252
+ correct_matches = (
253
+ np.ma.masked_equal(master_table, non_null_product) == detected_table
254
+ ).sum()
255
+ total_products = (master_table != non_null_product).sum()
256
+ score = correct_matches / total_products
257
+ # if sorted_xml_df is not None:
258
+ # annotate_df = sorted_xml_df[["xmin","ymin", "xmax", "ymax", "line_number","cls"]].astype(int)
259
+ # else:
260
+ annotate_df = sorted_df[
261
+ ["xmin", "ymin", "xmax", "ymax", "line_number", "cls"]
262
+ ].astype(int)
263
+
264
+ mask = master_table != non_null_product
265
+ m_detected_table = np.ma.masked_array(master_table, mask=mask)
266
+ m_annotated_table = np.ma.masked_array(detected_table, mask=mask)
267
+
268
+ # wrong_indexes = np.ravel_multi_index(master_table*mask != detected_table*mask, master_table.shape)
269
+ wrong_indexes = np.where(master_table != detected_table)
270
+ correct_indexes = np.where(master_table == detected_table)
271
+ annotated_planogram = annotate_planogram_compliance(
272
+ uploaded_img, annotate_df, correct_indexes, wrong_indexes, target_names
273
+ )
274
+ st.title("Target Products")
275
+ st.write(json.dumps(target_names))
276
+ st.title("The master planogram annotation")
277
+ st.write(
278
+ "The annotations are based on the index of products from Target products list "
279
+ )
280
+ st.write(json.dumps(master_annotations))
281
+
282
+ # https://github.com/streamlit/streamlit/issues/888
283
+ st.image(
284
+ [master, annotated_planogram, result_list[0][0]],
285
+ width=512,
286
+ caption=[
287
+ "Master planogram",
288
+ "Planogram Compliance",
289
+ "Planogram Predictions",
290
+ ],
291
+ channels="BGR",
292
+ )
293
+ # st.image([master, annotated_planogram], width=512, caption=["Master planogram", "Planogram Compliance"], channels="BGR")
294
+ st.title("Planogram Compiance score")
295
+ # st.write(f"{correct_matches} / {total_products}")
296
+ st.write(score)