SelimGilon commited on
Commit
b887004
·
1 Parent(s): d20170b
Files changed (2) hide show
  1. app.py +138 -141
  2. app_file.py +2 -2
app.py CHANGED
@@ -17,8 +17,8 @@ search_google = False
17
  # GOOGLE_CSE_ID = "b536303d151b94476"
18
  # GOOGLE_API_KEY = "AIzaSyBUvPKAZa2TddKYDJI9t0ac2A_JJqdgWHo"
19
  # GOOGLE_CSE_ID = "f3446c60c52cd4dc2"
20
- GOOGLE_API_KEY = "AIzaSyCoBYZK4khX_W5eW-AqEXKOclUIer6CiC8"
21
- GOOGLE_CSE_ID = "c3ba01991c1a14c7d"
22
  mode = 'local'
23
  # mode = 'rbf'
24
 
@@ -70,21 +70,23 @@ shops = {
70
  regex_price = r'(\d+\.?\d*) ?([€$])|([€$]) ?(\d+\.?\d*)'
71
 
72
 
73
- def app(img, selected_shop):
74
- if img is None:
75
- raise gr.Error("No file uploaded. Please upload an image.")
 
 
 
 
 
 
 
 
 
 
 
 
76
 
77
- # Check if the uploaded file is a PDF
78
- if selected_shop is None:
79
- raise gr.Error("Please select a shop.")
80
 
81
- try:
82
- image_annotated = section(img)
83
- pass
84
- except Exception as e:
85
- return gr.Error(f"An error occurred: {str(e)}")
86
-
87
- return image_annotated, hotspots_sku_links[selected_shop]
88
  def build_request(query, start=1, num=10, date_restrict=None, **params):
89
  request = {
90
  'key': GOOGLE_API_KEY,
@@ -112,6 +114,7 @@ def make_request(request):
112
  else:
113
  return None
114
 
 
115
  with gr.Blocks() as demo:
116
 
117
  with gr.Row():
@@ -127,6 +130,9 @@ with gr.Blocks() as demo:
127
  section_btn = gr.Button("Identify Hotspots")
128
  # selected_section = gr.Textbox(label="Selected Hotspot")
129
  selected_section = gr.Markdown(label="Selected Hotspot")
 
 
 
130
  def get_yolo_predictions(image, confidence_threshold):
131
  # Use Roboflow API to get predictions
132
  predictions = model.predict(image, confidence=confidence_threshold, overlap=10).json()
@@ -147,51 +153,23 @@ with gr.Blocks() as demo:
147
 
148
  def section(img, selected_shop, confidence_threshold):
149
  hostpots = []
150
- texts = []
151
  sku = []
152
- # Define your Google API key and Custom Search Engine ID
 
 
 
153
 
154
  #print("selected_shop:", selected_shop)
155
  search_url = shops[selected_shop]['url']
156
  ref_number_regex = shops[selected_shop]['regex']
157
  # print("search_url:", search_url)
158
  brands = shops[selected_shop]['brands'] if 'brands' in shops[selected_shop] else None
 
159
  if brands:
160
  brands = [brand.upper() for brand in brands]
161
 
162
  if mode == 'rbf':
163
  predictions = get_yolo_predictions(img)
164
- # print("-------")
165
- # for idx, pred in enumerate(predictions["predictions"]):
166
- # x_center = int(pred["x"])
167
- # y_center = int(pred["y"])
168
- # x = int(x_center - (pred["width"] / 2))
169
- # y = int(y_center - (pred["height"] / 2))
170
- # w = int(pred["width"])
171
- # h = int(pred["height"])
172
- # # Cropping the image to the bounding box
173
- # sub_image = img[y:y + h, x:x + w]
174
- # cv2.imwrite(f"sub_image_{idx}.jpg", sub_image)
175
- #
176
- # # Extract text using OCR
177
- # text = ocr(sub_image)
178
- # texts.append(text)
179
- #
180
- # # print("bbox", idx)
181
- # for object_number, text in enumerate(texts, start=1):
182
- # print("object", object_number)
183
- # # print("text", text)
184
- # ref_numbers = re.findall(ref_number_regex, text)
185
- # for ref in ref_numbers:
186
- # print("SKU:", ref)
187
- # # append 'M' before the ref number
188
- # search_query = search_url + urllib.parse.quote(ref)
189
- # if ref not in sku:
190
- # sku.append(ref)
191
- # # if search_query not in hotspots_sku_links:
192
- # hotspots_sku_links.append(search_query)
193
- # hostpots.append(((x, y, x + w, y + h), ref))
194
- # return (img, hostpots)
195
  else:
196
  # local inference
197
  results = get_yolo_predictions_local(img, confidence_threshold)
@@ -207,8 +185,6 @@ with gr.Blocks() as demo:
207
  w = int(coord[2] - coord[0])
208
  h = int(coord[3] - coord[1])
209
  sub_image = img[y:y + h, x:x + w]
210
-
211
-
212
  if shops[selected_shop]['url'] is None or shops[selected_shop]['url'] == "":
213
  # just append the hotspot to hostpots
214
  hostpots.append(((x, y, x + w, y + h), str(idx)))
@@ -216,110 +192,131 @@ with gr.Blocks() as demo:
216
 
217
  # Extract text using OCR
218
  text = ocr(sub_image)
219
- texts.append(text)
220
 
221
- for object_number, text in enumerate(texts, start=1):
222
- #print("object", object_number)
223
- #print("text", text)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
224
  ref_numbers = []
225
- if selected_shop == "Decathlon":
226
- full_match = re.search(ref_number_regex, text)
227
- if full_match:
228
- #print("FULL MATCH: ", full_match)
229
- # Extracting all numbers from the captured sequence
230
- numbers_string = full_match.group(1)
231
- ref_numbers = re.findall(r'\d+', numbers_string)
232
- else:
233
- ref_numbers = re.findall(ref_number_regex, text)
234
-
235
- if selected_shop == "Canadian Tire":
236
- temp_ref_numbers = ref_numbers
237
- found_skus_new = []
238
- ref_numbers = []
239
- split = False
240
- for ref_sku in temp_ref_numbers:
241
- if '/' in ref_sku:
242
- split = True
243
- sku_split = ref_sku.split('/')
244
- sku_last = sku_split[-1]
245
- length = len(sku_last)
246
- base_number = sku_split[0][:-length]
247
- ref_numbers.append(sku_split[0])
248
- # base number + sku for each sku in sku_split except the first one
249
- for i in range(1, len(sku_split)):
250
- ref_numbers.append(base_number + sku_split[i])
251
-
252
- if split == False:
253
- ref_numbers = temp_ref_numbers
254
-
255
-
256
- #print("REF NUMBERS: ", ref_numbers)
257
-
258
- matches = re.findall(regex_price, text)
259
- prices = []
260
- for match in matches:
261
- if match[0]: # If the first group is not empty, the format is "price currency"
262
- prices.append(match[0] + match[1])
263
- else: # Otherwise, the format is "currency price"
264
- prices.append(match[2] + match[3])
265
- # price = prices[0] if len(prices) > 0 else ""
266
- #print("PRICES: ", prices)
267
-
268
- if brands:
269
- # print("BRANDS: yes")
270
- # Extracting the product name
271
- lines = text.split('\n')
272
- product_name = ""
273
- found_brand = False
274
- name_started = False
275
- for line in lines:
276
- if any(brand in line for brand in brands):
277
- found_brand = True
278
- #print("FOUND BRAND", line)
279
  continue
280
- if found_brand:
281
- #print('current line:', line)
282
- if line.strip() == "": # Skip blank lines
283
- continue
284
- if name_started and (line[0].isupper() or any(char.isdigit() for char in line)):
285
- break
286
- product_name += line.strip() + " "
287
- name_started = True
288
- product_name = product_name.strip()
289
 
290
- else:
291
- # Regex to match sequences of uppercase letters
292
- uppercase_words = re.findall(r'\b[A-Z]+\b', text)
293
 
294
- # Joining the extracted words with a space
295
- product_name = ' '.join(uppercase_words)
296
 
297
  #print("PRODUCT NAME: ", product_name)
298
 
299
- for ref in ref_numbers:
300
- if search_google:
301
- # Use Google Search API to find items with the SKU
302
- to_seach = str(selected_shop) + ' ' + str(ref)
303
- # print("to_search: ", to_seach)
304
- request = build_request(to_seach)
305
- search_query = make_request(request)
306
- # print(f"First Result URL: {search_query}")
307
- if search_query is None:
308
- search_query = search_url + urllib.parse.quote(ref)
309
- else:
310
  search_query = search_url + urllib.parse.quote(ref)
311
- if ref not in sku:
312
- sku.append(ref)
313
- # if search_query not in hotspots_sku_links:
314
- hotspots_sku_links.append([{'sku': ref, 'url': search_query, 'prices': prices, 'product_name': product_name}])
315
- hostpots.append(((int(coord[0]), int(coord[1]), int(coord[2]), int(coord[3])), str(ref)))
316
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
317
  print("hotspots_sku_links: ", hotspots_sku_links)
 
 
318
  print("skus: ", sku)
319
- return (img, hostpots)
 
 
 
320
 
 
321
 
322
- section_btn.click(section, [img_input, selected_shop, confidence_threshold], img_output)
323
 
324
 
325
  def select_section(evt: gr.SelectData):
 
17
  # GOOGLE_CSE_ID = "b536303d151b94476"
18
  # GOOGLE_API_KEY = "AIzaSyBUvPKAZa2TddKYDJI9t0ac2A_JJqdgWHo"
19
  # GOOGLE_CSE_ID = "f3446c60c52cd4dc2"
20
+ # GOOGLE_API_KEY = "AIzaSyCoBYZK4khX_W5eW-AqEXKOclUIer6CiC8"
21
+ # GOOGLE_CSE_ID = "c3ba01991c1a14c7d"
22
  mode = 'local'
23
  # mode = 'rbf'
24
 
 
70
  regex_price = r'(\d+\.?\d*) ?([€$])|([€$]) ?(\d+\.?\d*)'
71
 
72
 
73
+ # def app(img, selected_shop):
74
+ # if img is None:
75
+ # raise gr.Error("No file uploaded. Please upload an image.")
76
+ #
77
+ # # Check if the uploaded file is a PDF
78
+ # if selected_shop is None:
79
+ # raise gr.Error("Please select a shop.")
80
+ #
81
+ # try:
82
+ # image_annotated = section(img)
83
+ # pass
84
+ # except Exception as e:
85
+ # return gr.Error(f"An error occurred: {str(e)}")
86
+ #
87
+ # return image_annotated, hotspots_sku_links[selected_shop]
88
 
 
 
 
89
 
 
 
 
 
 
 
 
90
  def build_request(query, start=1, num=10, date_restrict=None, **params):
91
  request = {
92
  'key': GOOGLE_API_KEY,
 
114
  else:
115
  return None
116
 
117
+
118
  with gr.Blocks() as demo:
119
 
120
  with gr.Row():
 
130
  section_btn = gr.Button("Identify Hotspots")
131
  # selected_section = gr.Textbox(label="Selected Hotspot")
132
  selected_section = gr.Markdown(label="Selected Hotspot")
133
+ product_dataframe = gr.Dataframe(label="Products Found")
134
+
135
+
136
  def get_yolo_predictions(image, confidence_threshold):
137
  # Use Roboflow API to get predictions
138
  predictions = model.predict(image, confidence=confidence_threshold, overlap=10).json()
 
153
 
154
  def section(img, selected_shop, confidence_threshold):
155
  hostpots = []
 
156
  sku = []
157
+ product_table_data = []
158
+
159
+ global hotspots_sku_links
160
+ hotspots_sku_links = []
161
 
162
  #print("selected_shop:", selected_shop)
163
  search_url = shops[selected_shop]['url']
164
  ref_number_regex = shops[selected_shop]['regex']
165
  # print("search_url:", search_url)
166
  brands = shops[selected_shop]['brands'] if 'brands' in shops[selected_shop] else None
167
+
168
  if brands:
169
  brands = [brand.upper() for brand in brands]
170
 
171
  if mode == 'rbf':
172
  predictions = get_yolo_predictions(img)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
173
  else:
174
  # local inference
175
  results = get_yolo_predictions_local(img, confidence_threshold)
 
185
  w = int(coord[2] - coord[0])
186
  h = int(coord[3] - coord[1])
187
  sub_image = img[y:y + h, x:x + w]
 
 
188
  if shops[selected_shop]['url'] is None or shops[selected_shop]['url'] == "":
189
  # just append the hotspot to hostpots
190
  hostpots.append(((x, y, x + w, y + h), str(idx)))
 
192
 
193
  # Extract text using OCR
194
  text = ocr(sub_image)
 
195
 
196
+ if selected_shop == "Latulippe":
197
+ # if there is a 'i' between a "M" and a number, it is a sku. Replace the 'i' with a '1'
198
+ text = re.sub(r'Mi(\d+)', r'M1\1', text)
199
+
200
+ # for object_number, text in enumerate(texts, start=1):
201
+ #print("object", object_number)
202
+ print("text -----", text)
203
+ ref_numbers = []
204
+ if selected_shop == "Decathlon":
205
+ full_match = re.search(ref_number_regex, text)
206
+ if full_match:
207
+ print("FULL MATCH: ", full_match)
208
+ # Extracting all numbers from the captured sequence
209
+ numbers_string = full_match.group(1)
210
+ ref_numbers = re.findall(r'\d+', numbers_string)
211
+ print("REF NUMBERS: ", ref_numbers)
212
+ else:
213
+ ref_numbers = re.findall(ref_number_regex, text)
214
+ # print("REF NUMBERS: ", ref_numbers)
215
+
216
+ if selected_shop == "Canadian Tire":
217
+ temp_ref_numbers = ref_numbers
218
  ref_numbers = []
219
+ split = False
220
+ for ref_sku in temp_ref_numbers:
221
+ if '/' in ref_sku:
222
+ split = True
223
+ sku_split = ref_sku.split('/')
224
+ sku_last = sku_split[-1]
225
+ length = len(sku_last)
226
+ base_number = sku_split[0][:-length]
227
+ ref_numbers.append(sku_split[0])
228
+ # base number + sku for each sku in sku_split except the first one
229
+ for i in range(1, len(sku_split)):
230
+ ref_numbers.append(base_number + sku_split[i])
231
+
232
+ if split == False:
233
+ ref_numbers = temp_ref_numbers
234
+
235
+ matches = re.findall(regex_price, text)
236
+ prices = []
237
+ for match in matches:
238
+ if match[0]: # If the first group is not empty, the format is "price currency"
239
+ prices.append(match[0] + match[1])
240
+ else: # Otherwise, the format is "currency price"
241
+ prices.append(match[2] + match[3])
242
+ # price = prices[0] if len(prices) > 0 else ""
243
+ #print("PRICES: ", prices)
244
+
245
+ if brands:
246
+ # print("BRANDS: yes")
247
+ # Extracting the product name
248
+ lines = text.split('\n')
249
+ product_name = ""
250
+ found_brand = False
251
+ name_started = False
252
+ for line in lines:
253
+ if any(brand in line for brand in brands):
254
+ found_brand = True
255
+ #print("FOUND BRAND", line)
256
+ continue
257
+ if found_brand:
258
+ #print('current line:', line)
259
+ if line.strip() == "": # Skip blank lines
 
 
 
 
 
 
 
 
 
 
 
 
 
260
  continue
261
+ if name_started and (line[0].isupper() or any(char.isdigit() for char in line)):
262
+ break
263
+ product_name += line.strip() + " "
264
+ name_started = True
265
+ product_name = product_name.strip()
 
 
 
 
266
 
267
+ else:
268
+ # Regex to match sequences of uppercase letters
269
+ uppercase_words = re.findall(r'\b[A-Z]+\b', text)
270
 
271
+ # Joining the extracted words with a space
272
+ product_name = ' '.join(uppercase_words)
273
 
274
  #print("PRODUCT NAME: ", product_name)
275
 
276
+ for ref in ref_numbers:
277
+ print("ref", ref)
278
+ if search_google:
279
+ # Use Google Search API to find items with the SKU
280
+ to_seach = str(selected_shop) + ' ' + str(ref)
281
+ # print("to_search: ", to_seach)
282
+ request = build_request(to_seach)
283
+ search_query = make_request(request)
284
+ # print(f"First Result URL: {search_query}")
285
+ if search_query is None:
 
286
  search_query = search_url + urllib.parse.quote(ref)
287
+ else:
288
+ search_query = search_url + urllib.parse.quote(ref)
289
+ if ref not in sku:
290
+ sku.append(ref)
291
+ # if search_query not in hotspots_sku_links:
292
+ hotspots_sku_links.append([{'sku': ref, 'url': search_query, 'prices': prices, 'product_name': product_name}])
293
+ hostpots.append(((int(coord[0]), int(coord[1]), int(coord[2]), int(coord[3])), str(ref)))
294
+
295
+ for data in hotspots_sku_links:
296
+ for item in data:
297
+ product_table_data.append({
298
+ 'Reference Number': item['sku'],
299
+ 'Product Name': item['product_name'] if item['product_name'] else "Not Found",
300
+ # 'Price': ", ".join(item['prices']) if item['prices'] else " ",
301
+ 'URL': item['url']
302
+ })
303
+
304
+ # Create a DataFrame
305
+ product_dataframe_data = pd.DataFrame(product_table_data)
306
+
307
+ # flattern the list hotspots_sku_links
308
+ # hotspots_sku_links = [item for sublist in hotspots_sku_links for item in sublist]
309
  print("hotspots_sku_links: ", hotspots_sku_links)
310
+ print('length of hotspots_sku_links: ', len(hotspots_sku_links))
311
+ print('shape of hotspots_sku_links: ', np.shape(hotspots_sku_links))
312
  print("skus: ", sku)
313
+ print('length of skus: ', len(sku))
314
+ assert len(hotspots_sku_links) == len(sku)
315
+ return (img, hostpots), product_dataframe_data
316
+
317
 
318
+ section_btn.click(section, [img_input, selected_shop, confidence_threshold], [img_output, product_dataframe])
319
 
 
320
 
321
 
322
  def select_section(evt: gr.SelectData):
app_file.py CHANGED
@@ -17,8 +17,8 @@ search_google = False
17
  # GOOGLE_CSE_ID = "b536303d151b94476"
18
  # GOOGLE_API_KEY = "AIzaSyBUvPKAZa2TddKYDJI9t0ac2A_JJqdgWHo"
19
  # GOOGLE_CSE_ID = "f3446c60c52cd4dc2"
20
- GOOGLE_API_KEY = "AIzaSyCoBYZK4khX_W5eW-AqEXKOclUIer6CiC8"
21
- GOOGLE_CSE_ID = "c3ba01991c1a14c7d"
22
  mode = 'local'
23
  # mode = 'rbf'
24
 
 
17
  # GOOGLE_CSE_ID = "b536303d151b94476"
18
  # GOOGLE_API_KEY = "AIzaSyBUvPKAZa2TddKYDJI9t0ac2A_JJqdgWHo"
19
  # GOOGLE_CSE_ID = "f3446c60c52cd4dc2"
20
+ # GOOGLE_API_KEY = "AIzaSyCoBYZK4khX_W5eW-AqEXKOclUIer6CiC8"
21
+ # GOOGLE_CSE_ID = "c3ba01991c1a14c7d"
22
  mode = 'local'
23
  # mode = 'rbf'
24