leedoming commited on
Commit
c9fcc85
ยท
verified ยท
1 Parent(s): 76b64b0

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +116 -79
app.py CHANGED
@@ -239,9 +239,32 @@ def process_segmentation(image):
239
  return []
240
 
241
  def search_similar_items(image, mask=None, top_k=10):
242
- """๋ฉ€ํ‹ฐ๋ชจ๋‹ฌ ๊ฒ€์ƒ‰ ์ˆ˜ํ–‰"""
243
  try:
244
- collection = setup_multimodal_collection()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
245
 
246
  # ๋งˆ์Šคํฌ ์ ์šฉ
247
  if mask is not None:
@@ -250,99 +273,113 @@ def search_similar_items(image, mask=None, top_k=10):
250
  query_image = Image.fromarray(masked_image.astype(np.uint8))
251
  else:
252
  query_image = image
253
-
254
- # ๊ฒ€์ƒ‰ ์ˆ˜ํ–‰
255
- results = collection.query(
256
- query_images=[np.array(query_image)],
257
- n_results=top_k,
258
- include=['metadatas', 'distances']
259
- )
260
 
261
- if not results or 'metadatas' not in results:
262
- return []
263
-
264
- similar_items = []
265
- for metadata, distance in zip(results['metadatas'][0], results['distances'][0]):
266
- # L2 ๊ฑฐ๋ฆฌ๋ฅผ ์ฝ”์‚ฌ์ธ ์œ ์‚ฌ๋„๋กœ ๋ณ€ํ™˜
267
- # ์ •๊ทœํ™”๋œ ๋ฒกํ„ฐ ๊ฐ„์˜ L2 ๊ฑฐ๋ฆฌ(d)์™€ ์ฝ”์‚ฌ์ธ ์œ ์‚ฌ๋„(cos_sim) ๊ด€๊ณ„:
268
- # d^2 = 2(1 - cos_sim)
269
- # cos_sim = 1 - (d^2/2)
270
- cosine_similarity = 1 - (distance ** 2 / 2)
271
-
272
- # -1~1 ๋ฒ”์œ„์˜ ์ฝ”์‚ฌ์ธ ์œ ์‚ฌ๋„๋ฅผ 0~100 ๋ฒ”์œ„๋กœ ๋ณ€ํ™˜
273
- similarity_score = ((cosine_similarity + 1) / 2) * 100
274
-
275
- item_data = metadata.copy()
276
- item_data['similarity_score'] = similarity_score
277
- similar_items.append(item_data)
278
-
279
- similar_items.sort(key=lambda x: x['similarity_score'], reverse=True)
280
- return similar_items
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
281
 
282
  except Exception as e:
283
  logger.error(f"Multimodal search error: {e}")
284
  return []
285
 
286
- def update_db_with_multimodal():
287
- """DB๋ฅผ ๋ฉ€ํ‹ฐ๋ชจ๋‹ฌ ๋ฐฉ์‹์œผ๋กœ ์—…๋ฐ์ดํŠธ"""
288
- try:
289
- # ์ƒˆ ์ปฌ๋ ‰์…˜ ์ƒ์„ฑ
290
- collection = setup_multimodal_collection()
291
 
292
- # ๊ธฐ์กด ์ปฌ๋ ‰์…˜์—์„œ ๋ฐ์ดํ„ฐ ๊ฐ€์ ธ์˜ค๊ธฐ
293
- client = chromadb.PersistentClient(path="./clothesDB_11GmarketMusinsa")
294
- old_collection = client.get_collection("clothes")
295
- old_data = old_collection.get(include=['metadatas'])
296
 
297
- total_items = len(old_data['metadatas'])
298
- progress_bar = st.progress(0)
299
- status_text = st.empty()
300
 
301
- batch_size = 100
302
- successful_updates = 0
303
- failed_updates = 0
304
 
305
- for i in range(0, total_items, batch_size):
306
- batch = old_data['metadatas'][i:i + batch_size]
307
 
308
- images = []
309
- valid_metadatas = []
310
- valid_ids = []
311
 
312
- for metadata in batch:
313
- try:
314
- if 'image_url' in metadata:
315
- response = requests.get(metadata['image_url'])
316
- img = Image.open(io.BytesIO(response.content)).convert('RGB')
317
- images.append(np.array(img))
318
- valid_metadatas.append(metadata)
319
- valid_ids.append(metadata.get('id', str(hash(metadata['image_url']))))
320
- successful_updates += 1
321
- except Exception as e:
322
- logger.error(f"Error processing image: {e}")
323
- failed_updates += 1
324
- continue
325
 
326
- if images:
327
- collection.add(
328
- ids=valid_ids,
329
- images=images,
330
- metadatas=valid_metadatas
331
- )
332
 
333
- # Update progress
334
- progress = (i + len(batch)) / total_items
335
- progress_bar.progress(progress)
336
- status_text.text(f"Processing: {i + len(batch)}/{total_items} items. "
337
- f"Success: {successful_updates}, Failed: {failed_updates}")
338
 
339
- status_text.text(f"Update completed. Successfully processed: {successful_updates}, "
340
- f"Failed: {failed_updates}")
341
- return True
342
 
343
- except Exception as e:
344
- logger.error(f"Multimodal DB update error: {e}")
345
- return False
346
 
347
  def show_similar_items(similar_items):
348
  """Display similar items in a structured format with similarity scores"""
 
239
  return []
240
 
241
  def search_similar_items(image, mask=None, top_k=10):
242
+ """๋‘ ๊ฐœ์˜ ๋ฉ€ํ‹ฐ๋ชจ๋‹ฌ ์ปฌ๋ ‰์…˜์—์„œ ๊ฒ€์ƒ‰ ์ˆ˜ํ–‰"""
243
  try:
244
+ client = chromadb.PersistentClient(path="./fashion_multimodal_db")
245
+ embedding_function = CustomFashionEmbeddingFunction()
246
+ data_loader = ImageLoader()
247
+
248
+ # ๋‘ ์ปฌ๋ ‰์…˜ ๋ชจ๋‘ ๊ฐ€์ ธ์˜ค๊ธฐ
249
+ collections = []
250
+ collection_names = ["fashion_multimodal", "fashion_multimodal_v2"]
251
+
252
+ for name in collection_names:
253
+ try:
254
+ collection = client.get_collection(
255
+ name=name,
256
+ embedding_function=embedding_function,
257
+ data_loader=data_loader
258
+ )
259
+ collections.append(collection)
260
+ logger.info(f"Successfully connected to {name} collection")
261
+ except Exception as e:
262
+ logger.error(f"Error getting collection {name}: {e}")
263
+ continue
264
+
265
+ if not collections:
266
+ logger.error("No collections available for search")
267
+ return []
268
 
269
  # ๋งˆ์Šคํฌ ์ ์šฉ
270
  if mask is not None:
 
273
  query_image = Image.fromarray(masked_image.astype(np.uint8))
274
  else:
275
  query_image = image
 
 
 
 
 
 
 
276
 
277
+ # ๊ฐ ์ปฌ๋ ‰์…˜์—์„œ ๊ฒ€์ƒ‰ ์ˆ˜ํ–‰
278
+ all_results = []
279
+
280
+ for collection in collections:
281
+ try:
282
+ results = collection.query(
283
+ query_images=[np.array(query_image)],
284
+ n_results=top_k,
285
+ include=['metadatas', 'distances']
286
+ )
287
+
288
+ if results and 'metadatas' in results:
289
+ for metadata, distance in zip(results['metadatas'][0], results['distances'][0]):
290
+ # L2 ๊ฑฐ๋ฆฌ๋ฅผ ์ฝ”์‚ฌ์ธ ์œ ์‚ฌ๋„๋กœ ๋ณ€ํ™˜
291
+ cosine_similarity = 1 - (distance ** 2 / 2)
292
+ similarity_score = ((cosine_similarity + 1) / 2) * 100
293
+
294
+ item_data = metadata.copy()
295
+ item_data['similarity_score'] = similarity_score
296
+ all_results.append(item_data)
297
+
298
+ except Exception as e:
299
+ logger.error(f"Error searching in collection: {e}")
300
+ continue
301
+
302
+ # ๊ฒฐ๊ณผ ์ •๋ ฌ ๋ฐ ์ค‘๋ณต ์ œ๊ฑฐ
303
+ # URL ๊ธฐ๋ฐ˜์œผ๋กœ ์ค‘๋ณต ์ œ๊ฑฐ
304
+ seen_urls = set()
305
+ unique_results = []
306
+
307
+ for item in sorted(all_results, key=lambda x: x['similarity_score'], reverse=True):
308
+ url = item.get('image_url', '')
309
+ if url not in seen_urls:
310
+ seen_urls.add(url)
311
+ unique_results.append(item)
312
+
313
+ # top_k ๊ฐœ์ˆ˜๋งŒํผ ์ˆ˜์ง‘๋˜๋ฉด ์ข…๋ฃŒ
314
+ if len(unique_results) >= top_k:
315
+ break
316
+
317
+ return unique_results
318
 
319
  except Exception as e:
320
  logger.error(f"Multimodal search error: {e}")
321
  return []
322
 
323
+ # def update_db_with_multimodal():
324
+ # """DB๋ฅผ ๋ฉ€ํ‹ฐ๋ชจ๋‹ฌ ๋ฐฉ์‹์œผ๋กœ ์—…๋ฐ์ดํŠธ"""
325
+ # try:
326
+ # # ์ƒˆ ์ปฌ๋ ‰์…˜ ์ƒ์„ฑ
327
+ # collection = setup_multimodal_collection()
328
 
329
+ # # ๊ธฐ์กด ์ปฌ๋ ‰์…˜์—์„œ ๋ฐ์ดํ„ฐ ๊ฐ€์ ธ์˜ค๊ธฐ
330
+ # client = chromadb.PersistentClient(path="./clothesDB_11GmarketMusinsa")
331
+ # old_collection = client.get_collection("clothes")
332
+ # old_data = old_collection.get(include=['metadatas'])
333
 
334
+ # total_items = len(old_data['metadatas'])
335
+ # progress_bar = st.progress(0)
336
+ # status_text = st.empty()
337
 
338
+ # batch_size = 100
339
+ # successful_updates = 0
340
+ # failed_updates = 0
341
 
342
+ # for i in range(0, total_items, batch_size):
343
+ # batch = old_data['metadatas'][i:i + batch_size]
344
 
345
+ # images = []
346
+ # valid_metadatas = []
347
+ # valid_ids = []
348
 
349
+ # for metadata in batch:
350
+ # try:
351
+ # if 'image_url' in metadata:
352
+ # response = requests.get(metadata['image_url'])
353
+ # img = Image.open(io.BytesIO(response.content)).convert('RGB')
354
+ # images.append(np.array(img))
355
+ # valid_metadatas.append(metadata)
356
+ # valid_ids.append(metadata.get('id', str(hash(metadata['image_url']))))
357
+ # successful_updates += 1
358
+ # except Exception as e:
359
+ # logger.error(f"Error processing image: {e}")
360
+ # failed_updates += 1
361
+ # continue
362
 
363
+ # if images:
364
+ # collection.add(
365
+ # ids=valid_ids,
366
+ # images=images,
367
+ # metadatas=valid_metadatas
368
+ # )
369
 
370
+ # # Update progress
371
+ # progress = (i + len(batch)) / total_items
372
+ # progress_bar.progress(progress)
373
+ # status_text.text(f"Processing: {i + len(batch)}/{total_items} items. "
374
+ # f"Success: {successful_updates}, Failed: {failed_updates}")
375
 
376
+ # status_text.text(f"Update completed. Successfully processed: {successful_updates}, "
377
+ # f"Failed: {failed_updates}")
378
+ # return True
379
 
380
+ # except Exception as e:
381
+ # logger.error(f"Multimodal DB update error: {e}")
382
+ # return False
383
 
384
  def show_similar_items(similar_items):
385
  """Display similar items in a structured format with similarity scores"""