user-agent commited on
Commit
b7e7dbc
1 Parent(s): 9391706

Upload 5 files

Browse files
Files changed (5) hide show
  1. README (1).md +11 -0
  2. app.py +545 -0
  3. attributes_config.json +1116 -0
  4. color_config.json +90 -0
  5. requirements.txt +5 -0
README (1).md ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ title: Zero Shot Image Classification
3
+ emoji: 💻
4
+ colorFrom: blue
5
+ colorTo: gray
6
+ sdk: gradio
7
+ app_file: app.py
8
+ pinned: false
9
+ ---
10
+
11
+ Check out the configuration reference at https://huggingface.co/docs/hub/spaces#reference
app.py ADDED
@@ -0,0 +1,545 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import io
2
+ import ast
3
+ import json
4
+ import base64
5
+ import spaces
6
+ import requests
7
+ import numpy as np
8
+ import gradio as gr
9
+ from PIL import Image
10
+ from io import BytesIO
11
+ import face_recognition
12
+ from turtle import title
13
+ from openai import OpenAI
14
+ from collections import Counter
15
+ from transformers import pipeline
16
+
17
+ import urllib.request
18
+ from transformers import YolosImageProcessor, YolosForObjectDetection
19
+ import torch
20
+ import matplotlib.pyplot as plt
21
+ from torchvision.transforms import ToTensor, ToPILImage
22
+
23
+
24
+ client = OpenAI()
25
+
26
+ pipe = pipeline("zero-shot-image-classification", model="patrickjohncyh/fashion-clip")
27
+
28
+ color_file_path = 'color_config.json'
29
+ attributes_file_path = 'attributes_config.json'
30
+ import os
31
+ OPENAI_API_KEY = os.getenv("OPENAI_API_KEY")
32
+
33
+
34
+ # Open and read the COLOR JSON file
35
+ with open(color_file_path, 'r') as file:
36
+ color_data = json.load(file)
37
+
38
+ # Open and read the ATTRIBUTES JSON file
39
+ with open(attributes_file_path, 'r') as file:
40
+ attributes_data = json.load(file)
41
+
42
+ COLOURS_DICT = color_data['color_mapping']
43
+ ATTRIBUTES_DICT = attributes_data['attribute_mapping']
44
+
45
+
46
+ def shot(input, category, level):
47
+ output_dict = {}
48
+ if level == 'variant':
49
+ subColour, mainColour, score = get_colour(ast.literal_eval(str(input)), category)
50
+ openai_parsed_response = get_openAI_tags(ast.literal_eval(str(input)))
51
+ face_embeddings = get_face_embeddings(ast.literal_eval(str(input)))
52
+ cropped_images = get_cropped_images(ast.literal_eval(str(input)), category)
53
+
54
+ # Ensure all outputs are JSON serializable
55
+ output_dict['colors'] = {
56
+ "main": mainColour,
57
+ "sub": subColour,
58
+ "score": score
59
+ }
60
+ output_dict['image_mapping'] = openai_parsed_response
61
+ output_dict['face_embeddings'] = face_embeddings
62
+ output_dict['cropped_images'] = cropped_images
63
+
64
+ if level == 'product':
65
+ common_result = get_predicted_attributes(ast.literal_eval(str(input)), category)
66
+ output_dict['attributes'] = common_result
67
+ output_dict['subcategory'] = category
68
+
69
+ # # Convert the dictionary to a JSON-serializable format
70
+ # try:
71
+ # serialized_output = json.dumps(output_dict)
72
+ # except TypeError as e:
73
+ # print(f"Serialization Error: {e}")
74
+ # return {"error": "Serialization failed"}
75
+
76
+ return json.dumps(output_dict)
77
+
78
+
79
+
80
+ # @spaces.GPU
81
+ # def get_colour(image_urls, category):
82
+ # colourLabels = list(COLOURS_DICT.keys())
83
+ # for i in range(len(colourLabels)):
84
+ # colourLabels[i] = colourLabels[i] + " clothing: " + category
85
+
86
+ # responses = pipe(image_urls, candidate_labels=colourLabels)
87
+ # # Get the most common colour
88
+ # mainColour = responses[0][0]['label'].split(" clothing:")[0]
89
+
90
+
91
+ # if mainColour not in COLOURS_DICT:
92
+ # return None, None, None
93
+
94
+ # # Add category to the end of each label
95
+ # labels = COLOURS_DICT[mainColour]
96
+ # for i in range(len(labels)):
97
+ # labels[i] = labels[i] + " clothing: " + category
98
+
99
+ # # Run pipeline in one go
100
+ # responses = pipe(image_urls, candidate_labels=labels)
101
+ # subColour = responses[0][0]['label'].split(" clothing:")[0]
102
+
103
+ # return subColour, mainColour, responses[0][0]['score']
104
+
105
+ @spaces.GPU
106
+ def get_colour(image_urls, category):
107
+ # Prepare color labels
108
+ colourLabels = [f"{color} clothing: {category}" for color in COLOURS_DICT.keys()]
109
+ print("Colour Labels:", colourLabels) # Debug: Print colour labels
110
+ print("Image URLs:", image_urls) # Debug: Print image URLs
111
+
112
+ # Split labels into two batches
113
+ mid_index = len(colourLabels) // 2
114
+ first_batch = colourLabels[:mid_index]
115
+ second_batch = colourLabels[mid_index:]
116
+
117
+ # Process the first batch
118
+ responses_first_batch = pipe(image_urls, candidate_labels=first_batch)
119
+ # Get the top 3 from the first batch
120
+ top3_first_batch = sorted(responses_first_batch[0], key=lambda x: x['score'], reverse=True)[:3]
121
+
122
+ # Process the second batch
123
+ responses_second_batch = pipe(image_urls, candidate_labels=second_batch)
124
+ # Get the top 3 from the second batch
125
+ top3_second_batch = sorted(responses_second_batch[0], key=lambda x: x['score'], reverse=True)[:3]
126
+
127
+ # Combine the top 3 from each batch
128
+ combined_top6 = top3_first_batch + top3_second_batch
129
+ # Get the final top 3 from the combined list
130
+ final_top3 = sorted(combined_top6, key=lambda x: x['score'], reverse=True)[:3]
131
+
132
+ mainColour = final_top3[0]['label'].split(" clothing:")[0]
133
+
134
+ if mainColour not in COLOURS_DICT:
135
+ return None, None, None
136
+
137
+ # Get sub-colors for the main color
138
+ labels = [f"{label} clothing: {category}" for label in COLOURS_DICT[mainColour]]
139
+ print("Labels for pipe:", labels) # Debug: Confirm labels are correct
140
+
141
+ responses = pipe(image_urls, candidate_labels=labels)
142
+ subColour = responses[0][0]['label'].split(" clothing:")[0]
143
+
144
+ return subColour, mainColour, responses[0][0]['score']
145
+
146
+
147
+
148
+
149
+ @spaces.GPU
150
+ def get_predicted_attributes(image_urls, category):
151
+ # Assuming ATTRIBUTES_DICT and pipe are defined outside this function
152
+ attributes = list(ATTRIBUTES_DICT.get(category, {}).keys())
153
+
154
+ # Mapping of possible values per attribute
155
+ common_result = []
156
+ for attribute in attributes:
157
+ values = ATTRIBUTES_DICT.get(category, {}).get(attribute, [])
158
+
159
+ if len(values) == 0:
160
+ continue
161
+
162
+ # Adjust labels for the pipeline to be in format: "{attr}: {value}, clothing: {category}"
163
+ attribute_formatted = attribute.replace("colartype", "collar").replace("sleevelength", "sleeve length").replace("fabricstyle", "fabric")
164
+ values_formatted = [f"{attribute_formatted}: {value}, clothing: {category}" for value in values]
165
+
166
+ # Get the predicted values for the attribute
167
+ responses = pipe(image_urls, candidate_labels=values_formatted)
168
+ result = [response[0]['label'].split(", clothing:")[0] for response in responses]
169
+
170
+ # If attribute is details, then get the top 2 most common labels
171
+ if attribute_formatted == "details":
172
+ result += [response[1]['label'].split(", clothing:")[0] for response in responses]
173
+ common_result.append(Counter(result).most_common(2))
174
+ else:
175
+ common_result.append(Counter(result).most_common(1))
176
+
177
+ # Clean up the results into one long string
178
+ for i, result in enumerate(common_result):
179
+ common_result[i] = ", ".join([f"{x[0]}" for x in result])
180
+
181
+ result = {}
182
+
183
+ # Iterate through the list and split each item into key and value
184
+ for item in common_result:
185
+ # Split by ': ' to separate the key and value
186
+ key, value = item.split(': ', 1)
187
+
188
+ if key == "details":
189
+ details_split = value.split(" , ")
190
+ if len(details_split) == 2:
191
+ result["details_1"] = details_split[0]
192
+ result["details_2"] = details_split[1]
193
+ else:
194
+ result["details_1"] = value # If there's only one detail, assign it to details 1
195
+ else:
196
+ result[key] = value
197
+
198
+ return result
199
+
200
+ def get_openAI_tags(image_urls):
201
+ # Create list containing JSONs of each image URL
202
+ imageList = []
203
+ for image in image_urls:
204
+ imageList.append({"type": "image_url", "image_url": {"url": image}})
205
+
206
+ openai_response = client.chat.completions.create(
207
+ model="gpt-4o",
208
+ messages=[
209
+ {
210
+ "role": "system",
211
+ "content": [
212
+ {
213
+ "type": "text",
214
+ "text": "You're a tagging assistant, you will help label and tag product pictures for my online e-commerce platform. Your tasks will be to return which angle the product images were taken from. You will have to choose from 'full-body', 'half-body', 'side', 'back', or 'zoomed' angles. You should label each of the images with one of these labels depending on which you think fits best (ideally, every label should be used at least once, but only if there are 5 or more images), and should respond with an unformatted dictionary where the key is a string representation of the url index of the url and the value is the assigned label."
215
+ }
216
+ ]
217
+ },
218
+ {
219
+ "role": "user",
220
+ "content": imageList
221
+ },
222
+ ],
223
+ temperature=1,
224
+ max_tokens=500,
225
+ top_p=1,
226
+ frequency_penalty=0,
227
+ presence_penalty=0
228
+ )
229
+ response = json.loads(openai_response.choices[0].message.content)
230
+ return response
231
+
232
+
233
+ @spaces.GPU
234
+ def get_face_embeddings(image_urls):
235
+ # Initialize a dictionary to store the face encodings or errors
236
+ results = {}
237
+
238
+ # Loop through each image URL
239
+ for index, url in enumerate(image_urls):
240
+ try:
241
+ # Try to download the image from the URL
242
+ response = requests.get(url)
243
+ # Raise an exception if the response is not successful
244
+ response.raise_for_status()
245
+
246
+ # Load the image using face_recognition
247
+ image = face_recognition.load_image_file(BytesIO(response.content))
248
+
249
+ # Get the face encodings for all faces in the image
250
+ face_encodings = face_recognition.face_encodings(image)
251
+
252
+ # If no faces are detected, store an empty list
253
+ if not face_encodings:
254
+ results[str(index)] = []
255
+ else:
256
+ # Otherwise, store the first face encoding as a list
257
+ results[str(index)] = face_encodings[0].tolist()
258
+ except Exception as e:
259
+ # If any error occurs during the download or processing, store the error message
260
+ results[str(index)] = f"Error processing image: {str(e)}"
261
+
262
+ return results
263
+
264
+ # new
265
+ ACCURACY_THRESHOLD = 0.86
266
+
267
+ def open_image_from_url(url):
268
+ # Fetch the image from the URL
269
+ response = requests.get(url, stream=True)
270
+ response.raise_for_status() # Check if the request was successful
271
+
272
+ # Open the image using PIL
273
+ image = Image.open(BytesIO(response.content))
274
+
275
+ return image
276
+
277
+ # Add the main data to the session state
278
+ main = [['Product Id', 'Sku', 'Color', 'Images', 'Status', 'Category', 'Text']]
279
+
280
+ # This is the order of the categories list. NO NOT CHANGE. Just for visualization purposes
281
+ cats = ['shirt, blouse', 'top, t-shirt, sweatshirt', 'sweater', 'cardigan', 'jacket', 'vest', 'pants', 'shorts', 'skirt', 'coat', 'dress', 'jumpsuit', 'cape', 'glasses', 'hat', 'headband, head covering, hair accessory', 'tie', 'glove', 'watch', 'belt', 'leg warmer', 'tights, stockings', 'sock', 'shoe', 'bag, wallet', 'scarf', 'umbrella', 'hood', 'collar', 'lapel', 'epaulette', 'sleeve', 'pocket', 'neckline', 'buckle', 'zipper', 'applique', 'bead', 'bow', 'flower', 'fringe', 'ribbon', 'rivet', 'ruffle', 'sequin', 'tassel']
282
+
283
+ filter = ['dress', 'jumpsuit', 'cape', 'glasses', 'hat', 'headband, head covering, hair accessory', 'tie', 'glove', 'watch', 'belt', 'leg warmer', 'tights, stockings', 'sock', 'shoe', 'scarf', 'umbrella', 'hood', 'collar', 'lapel', 'epaulette', 'sleeve', 'pocket', 'neckline', 'buckle', 'zipper', 'applique', 'bead', 'bow', 'flower', 'fringe', 'ribbon', 'rivet', 'ruffle', 'sequin', 'tassel']
284
+
285
+ # 0 for full body, 1 for upper body, 2 for lower body, 3 for over body (jacket, coat, etc), 4 for accessories
286
+ yolo_mapping = {
287
+ 'shirt, blouse': 3,
288
+ 'top, t-shirt, sweatshirt' : 1,
289
+ 'sweater': 1,
290
+ 'cardigan': 1,
291
+ 'jacket': 3,
292
+ 'vest': 1,
293
+ 'pants': 2,
294
+ 'shorts': 2,
295
+ 'skirt': 2,
296
+ 'coat': 3,
297
+ 'dress': 0,
298
+ 'jumpsuit': 0,
299
+ 'bag, wallet': 4
300
+ }
301
+
302
+ # First line full body, second line upper body, third line lower body, fourth line over body, fifth line accessories
303
+ label_mapping = [
304
+ ['women-dress-mini', 'women-dress-dress', 'women-dress-maxi', 'women-dress-midi', 'women-playsuitsjumpsuits-playsuit', 'women-playsuitsjumpsuits-jumpsuit', 'women-coords-coords', 'women-swimwear-onepieces', 'women-swimwear-bikinisets'],
305
+ ['women-sweatersknits-cardigan', 'women-top-waistcoat', 'women-top-blouse', 'women-sweatersknits-blouse', 'women-sweatersknits-sweater', 'women-top-top', 'women-loungewear-hoodie', 'women-top-camistanks', 'women-top-tshirt', 'women-top-croptop', 'women-loungewear-sweatshirt', 'women-top-body'],
306
+ ['women-loungewear-joggers', 'women-bottom-trousers', 'women-bottom-leggings', 'women-bottom-jeans', 'women-bottom-shorts', 'women-bottom-skirt', 'women-loungewear-activewear', 'women-bottom-joggers'],
307
+ ['women-top-shirt', 'women-outwear-coatjacket', 'women-outwear-blazer', 'women-outwear-coatjacket', 'women-outwear-kimonos'],
308
+ ['women-accessories-bags']
309
+ ]
310
+
311
+ MODEL_NAME = "valentinafeve/yolos-fashionpedia"
312
+
313
+ feature_extractor = YolosImageProcessor.from_pretrained('hustvl/yolos-small')
314
+ model = YolosForObjectDetection.from_pretrained(MODEL_NAME)
315
+
316
+ def get_category_index(category):
317
+ # Find index of label mapping
318
+ for i, labels in enumerate(label_mapping):
319
+ if category in labels:
320
+ break
321
+ return i
322
+
323
+ def get_yolo_index(category):
324
+ # Find index of yolo mapping
325
+ return yolo_mapping[category]
326
+
327
+ def fix_channels(t):
328
+ """
329
+ Some images may have 4 channels (transparent images) or just 1 channel (black and white images), in order to let the images have only 3 channels. I am going to remove the fourth channel in transparent images and stack the single channel in back and white images.
330
+ :param t: Tensor-like image
331
+ :return: Tensor-like image with three channels
332
+ """
333
+ if len(t.shape) == 2:
334
+ return ToPILImage()(torch.stack([t for i in (0, 0, 0)]))
335
+ if t.shape[0] == 4:
336
+ return ToPILImage()(t[:3])
337
+ if t.shape[0] == 1:
338
+ return ToPILImage()(torch.stack([t[0] for i in (0, 0, 0)]))
339
+ return ToPILImage()(t)
340
+
341
+ def idx_to_text(i):
342
+ return cats[i]
343
+
344
+ # Random colors used for visualization
345
+ COLORS = [[0.000, 0.447, 0.741], [0.850, 0.325, 0.098], [0.929, 0.694, 0.125],
346
+ [0.494, 0.184, 0.556], [0.466, 0.674, 0.188], [0.301, 0.745, 0.933]]
347
+
348
+ # for output bounding box post-processing
349
+ def box_cxcywh_to_xyxy(x):
350
+ x_c, y_c, w, h = x.unbind(1)
351
+ b = [(x_c - 0.5 * w), (y_c - 0.5 * h),
352
+ (x_c + 0.5 * w), (y_c + 0.5 * h)]
353
+ return torch.stack(b, dim=1)
354
+
355
+ def rescale_bboxes(out_bbox, size):
356
+ img_w, img_h = size
357
+ b = box_cxcywh_to_xyxy(out_bbox)
358
+ b = b * torch.tensor([img_w, img_h, img_w, img_h], dtype=torch.float32)
359
+
360
+ return b
361
+
362
+ def plot_results(pil_img, prob, boxes):
363
+ plt.figure(figsize=(16,10))
364
+ plt.imshow(pil_img)
365
+ ax = plt.gca()
366
+ colors = COLORS * 100
367
+ i = 0
368
+
369
+ crops = []
370
+ crop_classes = []
371
+ for p, (xmin, ymin, xmax, ymax), c in zip(prob, boxes.tolist(), colors):
372
+ cl = p.argmax()
373
+
374
+ # Save each box as an image
375
+ box_img = pil_img.crop((xmin, ymin, xmax, ymax))
376
+ crops.append(box_img)
377
+ crop_classes.append(idx_to_text(cl))
378
+
379
+ ax.add_patch(plt.Rectangle((xmin, ymin), xmax - xmin, ymax - ymin,
380
+ fill=False, color=c, linewidth=3))
381
+
382
+ ax.text(xmin, ymin, idx_to_text(cl), fontsize=10,
383
+ bbox=dict(facecolor=c, alpha=0.8))
384
+
385
+ i += 1
386
+
387
+ # Remove white padding all around the image
388
+ plt.axis('off')
389
+ plt.subplots_adjust(left=0, right=1, top=1, bottom=0)
390
+ output_img = plt.gcf()
391
+ plt.close()
392
+
393
+ return output_img, crops, crop_classes
394
+
395
+
396
+ def visualize_predictions(image, outputs, threshold=0.8):
397
+ # Keep only predictions with confidence >= threshold
398
+ probas = outputs.logits.softmax(-1)[0, :, :-1]
399
+ keep = probas.max(-1).values > threshold
400
+
401
+ # Convert predicted boxes from [0; 1] to image scales
402
+ bboxes_scaled = rescale_bboxes(outputs.pred_boxes[0, keep].cpu(), image.size)
403
+
404
+ # Get filtered probabilities and boxes based on the filter list
405
+ filter_set = set(filter)
406
+ filtered_probas_boxes = [
407
+ (proba, box) for proba, box in zip(probas[keep], bboxes_scaled)
408
+ if idx_to_text(proba.argmax()) not in filter_set
409
+ ]
410
+
411
+ # If there is a jumpsuit or dress detected, remove them if there are other clothes detected
412
+ contains_jumpsuit_or_dress = any(idx_to_text(proba.argmax()) in ["jumpsuit", "dress"] for proba, _ in filtered_probas_boxes)
413
+ if contains_jumpsuit_or_dress and len(filtered_probas_boxes) > 1:
414
+ filtered_probas_boxes = [
415
+ (proba, box) for proba, box in filtered_probas_boxes
416
+ if idx_to_text(proba.argmax()) not in ["jumpsuit", "dress"]
417
+ ]
418
+
419
+ # Remove duplicates: Only keep one box per class
420
+ unique_classes = set()
421
+ unique_filtered_probas_boxes = []
422
+ for proba, box in filtered_probas_boxes:
423
+ class_text = idx_to_text(proba.argmax())
424
+ if class_text not in unique_classes:
425
+ unique_classes.add(class_text)
426
+ unique_filtered_probas_boxes.append((proba, box))
427
+
428
+ # If there are remaining filtered probabilities, plot results
429
+ output_img = None
430
+ crops = None
431
+ crop_classes = None
432
+ if unique_filtered_probas_boxes:
433
+ final_probas, final_boxes = zip(*unique_filtered_probas_boxes)
434
+ output_img, crops, crop_classes = plot_results(image, list(final_probas), torch.stack(final_boxes))
435
+
436
+ # Return the classes of the detected objects
437
+ return [proba.argmax().item() for proba, _ in unique_filtered_probas_boxes], output_img, crops, crop_classes
438
+
439
+ @spaces.GPU
440
+ def get_objects(image, threshold=0.8):
441
+ class_counts = {}
442
+ image = fix_channels(ToTensor()(image))
443
+ image = image.resize((600, 800))
444
+
445
+ inputs = feature_extractor(images=image, return_tensors="pt")
446
+ outputs = model(**inputs)
447
+
448
+ detected_classes, output_img, crops, crop_classes = visualize_predictions(image, outputs, threshold=threshold)
449
+ for cl in detected_classes:
450
+ class_name = idx_to_text(cl)
451
+ if class_name not in class_counts:
452
+ class_counts[class_name] = 0
453
+ class_counts[class_name] += 1
454
+
455
+ if crop_classes is not None:
456
+ crop_classes = [get_yolo_index(c) for c in crop_classes]
457
+
458
+ return class_counts, output_img, crops, crop_classes
459
+
460
+ def encode_images_to_base64(cropped_list):
461
+ base64_images = []
462
+ for image in cropped_list:
463
+ with io.BytesIO() as buffer:
464
+ image.convert('RGB').save(buffer, format='JPEG')
465
+ base64_image = base64.b64encode(buffer.getvalue()).decode('utf-8')
466
+ base64_images.append(base64_image)
467
+ return base64_images
468
+
469
+
470
+ # def get_cropped_images(images,category):
471
+ # cropped_list = []
472
+ # resultsPerCategory = {}
473
+ # for num, image in enumerate(images):
474
+ # image = open_image_from_url(image)
475
+ # class_counts, output_img, cropped_images, cropped_classes = get_objects(image, 0.37)
476
+ # if not class_counts:
477
+ # continue
478
+
479
+ # # Get the inverse category as any other mapping label except the current one corresponding category
480
+ # inverse_category = [label for i, labels in enumerate(label_mapping) for label in labels if i != get_category_index(category) and i != 0]
481
+
482
+ # # If category is a cardigan, we don't recommend category indices 1 and 3
483
+ # if category == 'women-sweatersknits-cardigan':
484
+ # inverse_category = [label for i, labels in enumerate(label_mapping) for label in labels if i != get_category_index(category) and i != 1 and i != 3]
485
+
486
+ # for i, image in enumerate(cropped_images):
487
+ # cropped_category = cropped_classes[i]
488
+ # print(cropped_category, cropped_classes[i], get_category_index(category))
489
+
490
+ # specific_category = label_mapping[cropped_category]
491
+
492
+ # if cropped_category == get_category_index(category):
493
+ # continue
494
+
495
+ # cropped_list.append(image)
496
+
497
+
498
+ # base64_images = encode_images_to_base64(cropped_list)
499
+
500
+ # return base64_images
501
+
502
+
503
+
504
+
505
+ def get_cropped_images(images, category):
506
+ cropped_list = []
507
+ resultsPerCategory = {}
508
+ for num, image in enumerate(images):
509
+ image = open_image_from_url(image)
510
+ class_counts, output_img, cropped_images, cropped_classes = get_objects(image, 0.37)
511
+
512
+ if not class_counts:
513
+ continue
514
+
515
+ for i, image in enumerate(cropped_images):
516
+ cropped_list.append(image)
517
+
518
+ # Convert cropped images to base64 strings
519
+ base64_images = encode_images_to_base64(cropped_list)
520
+
521
+ return base64_images
522
+
523
+
524
+
525
+
526
+
527
+ # Define the Gradio interface with the updated components
528
+ iface = gr.Interface(
529
+ fn=shot,
530
+ inputs=[
531
+ gr.Textbox(label="Image URLs (starting with http/https) comma seperated "),
532
+ gr.Textbox(label="Category"),
533
+ gr.Textbox(label="Level; accepted 'variant' or 'product'")
534
+ ],
535
+ outputs="text",
536
+ examples=[
537
+ [['https://d2q1sfov6ca7my.cloudfront.net/eyJidWNrZXQiOiAiaGljY3VwLWltYWdlLWhvc3RpbmciLCAia2V5IjogIlc4MDAwMDAwMTM0LU9SL1c4MDAwMDAwMTM0LU9SLTEuanBnIiwgImVkaXRzIjogeyJyZXNpemUiOiB7IndpZHRoIjogODAwLCAiaGVpZ2h0IjogMTIwMC4wLCAiZml0IjogIm91dHNpZGUifX19',
538
+ 'https://d2q1sfov6ca7my.cloudfront.net/eyJidWNrZXQiOiAiaGljY3VwLWltYWdlLWhvc3RpbmciLCAia2V5IjogIlc4MDAwMDAwMTM0LU9SL1c4MDAwMDAwMTM0LU9SLTIuanBnIiwgImVkaXRzIjogeyJyZXNpemUiOiB7IndpZHRoIjogODAwLCAiaGVpZ2h0IjogMTIwMC4wLCAiZml0IjogIm91dHNpZGUifX19',
539
+ 'https://d2q1sfov6ca7my.cloudfront.net/eyJidWNrZXQiOiAiaGljY3VwLWltYWdlLWhvc3RpbmciLCAia2V5IjogIlc4MDAwMDAwMTM0LU9SL1c4MDAwMDAwMTM0LU9SLTMuanBnIiwgImVkaXRzIjogeyJyZXNpemUiOiB7IndpZHRoIjogODAwLCAiaGVpZ2h0IjogMTIwMC4wLCAiZml0IjogIm91dHNpZGUifX19'], "women-top-shirt","variant"]],
540
+ description="Add an image URL (starting with http/https) or upload a picture, and provide a list of labels separated by commas.",
541
+ title="Full product flow"
542
+ )
543
+
544
+ # Launch the interface
545
+ iface.launch()
attributes_config.json ADDED
@@ -0,0 +1,1116 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {"attribute_mapping":{
2
+ "women-sweatersknits-sweater": {
3
+ "fabricstyle": [
4
+ "Cable Knitted",
5
+ "Knitted"
6
+ ],
7
+ "pattern": [
8
+ "Floral",
9
+ "Patterned",
10
+ "Geometric",
11
+ "Solid",
12
+ "Graphic",
13
+ "Striped",
14
+ "Crochet",
15
+ "Dot Embroidered",
16
+ "Checked",
17
+ "Diamond Patterned"
18
+ ],
19
+ "sleevelength": [
20
+ "Sleeveless",
21
+ "Long Sleeve",
22
+ "Low Sleeve"
23
+ ],
24
+ "details": [
25
+ "Lace Detail ",
26
+ "Ruffled ",
27
+ "Buttoned ",
28
+ "Baloon Sleeve Lace Up Back ",
29
+ "Zippered ",
30
+ "Ribbed ",
31
+ "Arms Cut Out ",
32
+ "Ripped ",
33
+ "Detailed ",
34
+ "Pearl Detail ",
35
+ "Back Cut out ",
36
+ "Lace Up Back ",
37
+ "Open Shoulder ",
38
+ "One Shoulder ",
39
+ "Ribbed, Zippered",
40
+ "Ribbed Cut Out ",
41
+ "Zippered Neck ",
42
+ "Zippered Neck",
43
+ "Flare Sleeve ",
44
+ "Ribbed, Zippered ",
45
+ "Cold Shoulder Pearl Detail ",
46
+ "Asymmetrical ",
47
+ "Slit "
48
+ ],
49
+ "style": [
50
+ "Basic",
51
+ "Long Sleeve",
52
+ "Casual",
53
+ "Cropped",
54
+ "Crochet",
55
+ "Long",
56
+ "Cozy",
57
+ "Oversized",
58
+ "Loose",
59
+ "College"
60
+ ]
61
+ },
62
+ "women-top-croptop": {
63
+ "fabricstyle": [
64
+ "Denim",
65
+ "Cotton",
66
+ "Jersey",
67
+ "Lace",
68
+ "Woven",
69
+ "Knitted"
70
+ ],
71
+ "pattern": [
72
+ "Floral",
73
+ "Geometric",
74
+ "Solid",
75
+ "Striped",
76
+ "Crochet",
77
+ "Textured"
78
+ ],
79
+ "sleevelength": [
80
+ "Short Sleeve",
81
+ "Sleeveless",
82
+ "Long Sleeve"
83
+ ],
84
+ "details": [
85
+ "Basic",
86
+ "Half Zip",
87
+ "Ruched ",
88
+ "V-Shaped Front ",
89
+ "Ribbed ",
90
+ "Strappy",
91
+ "Ribbed",
92
+ "Metallic",
93
+ "Strappy ",
94
+ "Strappy Ruched Detail ",
95
+ "Drawstring ",
96
+ "Stone Embellished",
97
+ "Ribbed Neck Detail ",
98
+ "Halter, Tie back",
99
+ "Double Layer",
100
+ "Tie back",
101
+ "Crochet, Tassel",
102
+ "Zip Up Back Tassel Hem ",
103
+ "Crochet",
104
+ "Buttoned",
105
+ "Ribbed, Zippered "
106
+ ],
107
+ "style": [
108
+ "Basic",
109
+ "Boho",
110
+ "Corset",
111
+ "Cropped",
112
+ "Relaxed",
113
+ "Studded"
114
+ ]
115
+ },
116
+ "women-top-body": {
117
+ "fabricstyle": [
118
+ "Slinky Fabric",
119
+ "Velvet",
120
+ "Knitted",
121
+ "Woven"
122
+ ],
123
+ "pattern": [
124
+ "Solid"
125
+ ],
126
+ "sleevelength": [
127
+ "Sleeveless",
128
+ "Cap Sleeve",
129
+ "Long Sleeve"
130
+ ],
131
+ "details": [
132
+ "Diamente Strap",
133
+ "Stone Embellished",
134
+ "Backless ",
135
+ "Cut Out ",
136
+ "Ruched",
137
+ "Cut Out",
138
+ "Ribbed"
139
+ ],
140
+ "style": [
141
+ "Basic",
142
+ "Low Cut",
143
+ "Polo"
144
+ ]
145
+ },
146
+ "women-loungewear-sweatshirt": {
147
+ "fabricstyle": [
148
+ "Woven"
149
+ ],
150
+ "pattern": [
151
+ "Color Block",
152
+ "Solid",
153
+ "Graphic",
154
+ "Striped"
155
+ ],
156
+ "sleevelength": [
157
+ "Sleeveless",
158
+ "Long Sleeve"
159
+ ],
160
+ "details": [
161
+ "Neck Detail ",
162
+ "Kangaroo Pocket",
163
+ "Buttoned",
164
+ "Hooded, Drawstring "
165
+ ],
166
+ "style": [
167
+ "Basic",
168
+ "Cropped",
169
+ "Classic",
170
+ "Oversized",
171
+ "Relaxed"
172
+ ]
173
+ },
174
+ "women-dress-maxi": {
175
+ "fabricstyle": [
176
+ "Chiffon",
177
+ "Satin",
178
+ "Woven",
179
+ "Tulle",
180
+ "Knitted"
181
+ ],
182
+ "pattern": [
183
+ "Floral",
184
+ "Solid",
185
+ "Striped",
186
+ "Crochet",
187
+ "Ombre",
188
+ "Checked",
189
+ "Abstract"
190
+ ],
191
+ "sleevelength": [
192
+ "Short Sleeve",
193
+ "Sleeveless",
194
+ "Long Sleeve",
195
+ "Low Sleeve"
196
+ ],
197
+ "details": [
198
+ "Zip-up",
199
+ "Tie Back, Halter",
200
+ "Buttoned, Tiered",
201
+ "Spaghetti Strap, Tiered",
202
+ "Ruched ",
203
+ "Buttoned Front Slit ",
204
+ "Buttoned ",
205
+ "Pleated Front ",
206
+ "Tiered, Drawstring",
207
+ "Asymmetrical, Cut Out ",
208
+ "Tiered",
209
+ "Ribbed Hoodie ",
210
+ "Ruched",
211
+ "Cut Out ",
212
+ "Strappy, Slit",
213
+ "Tie Front, Tiered",
214
+ "Puff Sleeves",
215
+ "Bust Cut Out ",
216
+ "Backless",
217
+ "Back Cut Out, Slit ",
218
+ "Buttoned",
219
+ "Crochet, Textured",
220
+ "Cut Out",
221
+ "Slit "
222
+ ],
223
+ "style": [
224
+ "Basic",
225
+ "Maxi",
226
+ "Casual",
227
+ "Bodycon",
228
+ "Midi"
229
+ ]
230
+ },
231
+ "women-coords-coords": {
232
+ "fabricstyle": [
233
+ "Velvet",
234
+ "Jersey",
235
+ "Lace",
236
+ "Satin",
237
+ "Woven",
238
+ "Tweed",
239
+ "Tulle",
240
+ "Knitted"
241
+ ],
242
+ "pattern": [
243
+ "Geometric",
244
+ "Tie Dye",
245
+ "Solid",
246
+ "Striped",
247
+ "Animal Print",
248
+ "Lace",
249
+ "Ombre",
250
+ "Checked",
251
+ "Abstract"
252
+ ],
253
+ "sleevelength": [
254
+ "Short Sleeve",
255
+ "Sleeveless",
256
+ "Long Sleeve"
257
+ ],
258
+ "details": [
259
+ "Asymmetrical",
260
+ "Halter, Asymmetrical",
261
+ "Tie Up Detail ",
262
+ "Mesh",
263
+ "Drawstring ",
264
+ "Zippered Neck ",
265
+ "One Shoulder ",
266
+ "Pocket",
267
+ "Buttoned ",
268
+ "Buttoned",
269
+ "Belt Detail ",
270
+ "Zippered ",
271
+ "Bell Sleeves"
272
+ ]
273
+ },
274
+ "women-dress-mini": {
275
+ "fabricstyle": [
276
+ "Chiffon",
277
+ "Velvet",
278
+ "Denim",
279
+ "Sequin",
280
+ "Satin",
281
+ "Woven",
282
+ "Tulle",
283
+ "Knitted"
284
+ ],
285
+ "pattern": [
286
+ "Floral",
287
+ "Geometric",
288
+ "Solid",
289
+ "Striped",
290
+ "Animal Print",
291
+ "Ombre",
292
+ "Abstract"
293
+ ],
294
+ "sleevelength": [
295
+ "Short Sleeve",
296
+ "Sleeveless",
297
+ "Cap Sleeve",
298
+ "Long Sleeve"
299
+ ],
300
+ "details": [
301
+ "Tie Front",
302
+ "Drawstring",
303
+ "Combined",
304
+ "Strappy Tassel Detail ",
305
+ "Ruched ",
306
+ "Buttoned Padded Shoulder ",
307
+ "Buttoned ",
308
+ "Ruffle ",
309
+ "Back Cut Out ",
310
+ "Ruffle",
311
+ "Ruffled, Balloon Sleeves",
312
+ "Belt ",
313
+ "Balloon Sleeves",
314
+ "Front Tassel ",
315
+ "Side Cut Out ",
316
+ "Halter",
317
+ "Asymmetrical Tie ",
318
+ "Cut Out ",
319
+ "Halter, Tiered",
320
+ "Puff Sleeves",
321
+ "Button Detail",
322
+ "Buttoned, Pleated ",
323
+ "Back Cut Out",
324
+ "Diamente Tassel Trim ",
325
+ "Drawstring, Ruffle",
326
+ "Buttoned",
327
+ "Belt Detail "
328
+ ],
329
+ "style": [
330
+ "Skater",
331
+ "Mini",
332
+ "Cut Out, Buttoned, Belt Detail",
333
+ "Casual",
334
+ "T-shirt",
335
+ "Bodycon",
336
+ "A-line",
337
+ "Oversized",
338
+ "Shirt",
339
+ "Wrap"
340
+ ]
341
+ },
342
+ "women-top-blouse": {
343
+ "colartype": [
344
+ "round-neck"
345
+ ],
346
+ "fabricstyle": [
347
+ "Slinky Fabric",
348
+ "Chiffon",
349
+ "Velvet",
350
+ "Sequin",
351
+ "Mesh",
352
+ "Crochet",
353
+ "Lace",
354
+ "Woven",
355
+ "Tulle",
356
+ "woven",
357
+ "Knitted"
358
+ ],
359
+ "pattern": [
360
+ "Floral",
361
+ "Embroidered",
362
+ "Geometric",
363
+ "Solid",
364
+ "Striped",
365
+ "Embroderied",
366
+ "crochet",
367
+ "Abstract"
368
+ ],
369
+ "sleevelength": [
370
+ "Long Sleeve",
371
+ "Short Sleeve",
372
+ "short-sleeve",
373
+ "Cap Sleeve",
374
+ "Sleeveless"
375
+ ],
376
+ "details": [
377
+ "Ruched, Bust Cut Out",
378
+ "Buttoned ",
379
+ "Ribbed ",
380
+ "Lace Up Faux Fur Trim ",
381
+ "Ribbed",
382
+ "Ruffle, Textured, Button detail",
383
+ "Buttoned, Bell Sleeves",
384
+ "Balloon Sleeves",
385
+ "Ruffled",
386
+ "Ruched",
387
+ "Tie Front, Puff Sleeves",
388
+ "Semi-sheer",
389
+ "Puff Sleeve ",
390
+ "Tie Side",
391
+ "Lace Up ",
392
+ "Pearl Detail on the Neckline ",
393
+ "Puff Sleeve, Ruched ",
394
+ "Puff Sleeve, V-Shaped Front",
395
+ "Ribbed Cut Out ",
396
+ "Ruffled, Tiered, Drawstring",
397
+ "Smocked",
398
+ "Pocket",
399
+ "Buttoned",
400
+ "Cut Out"
401
+ ],
402
+ "style": [
403
+ "Boho",
404
+ "Vintage",
405
+ "Cropped",
406
+ "Crochet",
407
+ "Romantic",
408
+ "Oversized",
409
+ "Loose"
410
+ ]
411
+ },
412
+ "women-dress-midi": {
413
+ "fabricstyle": [
414
+ "Denim",
415
+ "Linen",
416
+ "Faux Leather",
417
+ "Lace",
418
+ "Woven",
419
+ "Knitted"
420
+ ],
421
+ "pattern": [
422
+ "Floral",
423
+ "Geometric",
424
+ "Solid",
425
+ "Mesh",
426
+ "Striped",
427
+ "Crochet",
428
+ "Smocked",
429
+ "Abstract"
430
+ ],
431
+ "sleevelength": [
432
+ "Short Sleeve",
433
+ "Sleeveless",
434
+ "Long Sleeve"
435
+ ],
436
+ "details": [
437
+ "Smocked, Balloon Sleeves",
438
+ "Drawstring",
439
+ "Spaghetti Strap, Tiered",
440
+ "Buttoned ",
441
+ "Belted",
442
+ "Tiered",
443
+ "Strappy ",
444
+ "Side Slit",
445
+ "Spaghetti Strap, Tie Front",
446
+ "Ruched Padded Shoulder ",
447
+ "Cut Out ",
448
+ "Puff Sleeves",
449
+ "Smocked, Tiered, Tie Strap",
450
+ "Side Slit, Balloon Sleeves",
451
+ "Wide Strap",
452
+ "Spaghetti Strap",
453
+ "Puff Sleeves, Tiered",
454
+ "Smocked",
455
+ "Buttoned",
456
+ "Cut Out",
457
+ "Slit "
458
+ ],
459
+ "style": [
460
+ "Boho",
461
+ "Casual",
462
+ "Bodycon",
463
+ "A-line",
464
+ "Oversized"
465
+ ]
466
+ },
467
+ "women-bottom-trousers": {
468
+ "pantsstyle": [
469
+ "Wide Leg"
470
+ ],
471
+ "risetype": [
472
+ "High Waist"
473
+ ],
474
+ "fabricstyle": [
475
+ "Denim",
476
+ "Linen",
477
+ "Mesh",
478
+ "Cotton",
479
+ "Faux Leather",
480
+ "Lace",
481
+ "Satin",
482
+ "Woven",
483
+ "Tweed",
484
+ "Knitted"
485
+ ],
486
+ "pattern": [
487
+ "Crochet",
488
+ "Geometric",
489
+ "Solid",
490
+ "Striped"
491
+ ],
492
+ "details": [
493
+ "Elastic Waist, Pocket ",
494
+ "Pleated ",
495
+ "Pleated, Belt",
496
+ "Drawstring",
497
+ "Elastic Waist ",
498
+ "Elastic Waist, Drawstring",
499
+ "Elastic Waist",
500
+ "Slit ",
501
+ "Drawstring ",
502
+ "Sheer",
503
+ "Belt",
504
+ "Drawstring, Pocket",
505
+ "Belt Detail",
506
+ "Elastic Waist, Pocket",
507
+ "Pocket ",
508
+ "Zippered, Slit ",
509
+ "Pleated, Waist Detail",
510
+ "Boho",
511
+ "Side slits",
512
+ "Drawstring, Pocket detail",
513
+ "Tassel Hem ",
514
+ "Belt Detail ",
515
+ "Pleated",
516
+ "Elastic Waist, Belt Detail"
517
+ ]
518
+ },
519
+ "women-bottom-skirt": {
520
+ "fabricstyle": [
521
+ "Denim",
522
+ "Linen",
523
+ "Faux Leather",
524
+ "Satin",
525
+ "Woven",
526
+ "Tweed",
527
+ "Knitted"
528
+ ],
529
+ "pattern": [
530
+ "Floral",
531
+ "Embroidered",
532
+ "Animal Printed",
533
+ "Solid",
534
+ "Sequin",
535
+ "Zebra Print",
536
+ "Openwork",
537
+ "Spot Print",
538
+ "Embroderied",
539
+ "Checked"
540
+ ],
541
+ "details": [
542
+ "Tie Front",
543
+ "Drawstring, Buttoned",
544
+ "Pleated ",
545
+ "Pleated, Belt",
546
+ "Folded Belt ",
547
+ "Drawstring",
548
+ "Elastic Waist",
549
+ "Front Slit",
550
+ "Asymmetrical, Buttoned ",
551
+ "Zippered",
552
+ "Tiered, Elastic Waist",
553
+ "Elastic Waist, Slit ",
554
+ "Elastic Waist, Basic",
555
+ "Ribbed",
556
+ "Pocket detail",
557
+ "Seamless Hem and Belt ",
558
+ "Pleated, Double Waistband",
559
+ "Belt ",
560
+ "Belt",
561
+ "Elastic Waist, Tiered",
562
+ "Ruffled",
563
+ "Front Slit ",
564
+ "Belt Detail",
565
+ "Elastic Waist, Pleated",
566
+ "Waist Detail, Pleated",
567
+ "Pocket ",
568
+ "Slit",
569
+ "Wrap, Tie Side",
570
+ "Asymmetrical",
571
+ "Drawstring, Ruffle",
572
+ "Buttoned",
573
+ "Belt Detail ",
574
+ "Pleated",
575
+ "Slit "
576
+ ]
577
+ },
578
+ "women-bottom-leggings": {
579
+ "fabricstyle": [
580
+ "Faux Leather",
581
+ "Woven"
582
+ ],
583
+ "pattern": [
584
+ "Solid"
585
+ ],
586
+ "details": [
587
+ "Zippered ",
588
+ "Ribbed "
589
+ ]
590
+ },
591
+ "women-bottom-jeans": {
592
+ "fabricstyle": [
593
+ "Denim"
594
+ ],
595
+ "pattern": [
596
+ "Solid"
597
+ ],
598
+ "details": [
599
+ "Diamente Tassel Pocket ",
600
+ "Metallic",
601
+ "Reversed Fabric ",
602
+ "Ribbon Belt ",
603
+ "Tassel Hem ",
604
+ "Pocket ",
605
+ "Ribbed ",
606
+ "Fur Hem ",
607
+ "Slit "
608
+ ]
609
+ },
610
+ "women-outwear-blazer": {
611
+ "fabricstyle": [
612
+ "Tweed",
613
+ "Woven"
614
+ ],
615
+ "pattern": [
616
+ "Collar",
617
+ "Solid"
618
+ ],
619
+ "sleevelength": [
620
+ "Long Sleeve"
621
+ ],
622
+ "details": [
623
+ "Pocket ",
624
+ "Ruched Front Slit ",
625
+ "Buttoned ",
626
+ "Pocket Detail"
627
+ ],
628
+ "style": [
629
+ "Blazer",
630
+ "Classic",
631
+ "Cropped"
632
+ ]
633
+ },
634
+ "women-top-shirt": {
635
+ "fabricstyle": [
636
+ "Organza",
637
+ "Chiffon",
638
+ "Denim",
639
+ "Muslin",
640
+ "Linen",
641
+ "Cotton",
642
+ "Satin",
643
+ "Woven",
644
+ "Plisse"
645
+ ],
646
+ "pattern": [
647
+ "Embroidered",
648
+ "Geometric",
649
+ "Solid",
650
+ "Striped"
651
+ ],
652
+ "sleevelength": [
653
+ "Short Sleeve",
654
+ "Sleeveless",
655
+ "Long Sleeve"
656
+ ],
657
+ "details": [
658
+ "Lace Up Back",
659
+ "Loose Sleeves",
660
+ "Gem Detail ",
661
+ "Bow Details on the Neck ",
662
+ "Backless ",
663
+ "Detailed ",
664
+ "Drawstring, Ruffle, ",
665
+ "Ruched ",
666
+ "Back Cut out Lace Detail ",
667
+ "Buttoned ",
668
+ "Pocket",
669
+ "Sheer",
670
+ "Button Detail",
671
+ "Pocket ",
672
+ "Pocket, Belt Detail",
673
+ "Relaxed",
674
+ "Buttoned",
675
+ "Laser Cut Detailed"
676
+ ],
677
+ "style": [
678
+ "Basic",
679
+ "Boho",
680
+ "Casual",
681
+ "Vintage",
682
+ "Patchy",
683
+ "Cropped",
684
+ "Crochet",
685
+ "Classic",
686
+ "Oversized",
687
+ "Relaxed",
688
+ "Loose"
689
+ ]
690
+ },
691
+ "women-outwear-coatjacket": {
692
+ "fabricstyle": [
693
+ "Denim",
694
+ "Paperbag",
695
+ "Faux Leather",
696
+ "Woven",
697
+ "Patent Leather",
698
+ "Tweed",
699
+ "Corduroy"
700
+ ],
701
+ "pattern": [
702
+ "Collar",
703
+ "Solid",
704
+ "Block Coloured"
705
+ ],
706
+ "sleevelength": [
707
+ "Sleeveless",
708
+ "Long Sleeve"
709
+ ],
710
+ "details": [
711
+ "Belt Detail",
712
+ "Zipper ",
713
+ "Pocket Ruched Back ",
714
+ "Lace Up ",
715
+ "Zipper, Padded ",
716
+ "Pocket Seamless Hem ",
717
+ "Drawstring ",
718
+ "Buttoned, Pocket",
719
+ "Buttoned ",
720
+ "Pocket, Drawstring ",
721
+ "Pocket",
722
+ "Buttoned, Belt",
723
+ "Pocket ",
724
+ "Patchy Hooded Back Detail ",
725
+ "Pocket, Buttoned ",
726
+ "Seamless Hem "
727
+ ],
728
+ "style": [
729
+ "Oversized",
730
+ "Short",
731
+ "Long",
732
+ "Cropped"
733
+ ]
734
+ },
735
+ "women-top-waistcoat": {
736
+ "fabricstyle": [
737
+ "Woven",
738
+ "Denim",
739
+ "Knitted"
740
+ ],
741
+ "pattern": [
742
+ "Checked",
743
+ "Solid",
744
+ "Striped"
745
+ ],
746
+ "sleevelength": [
747
+ "Sleeveless"
748
+ ],
749
+ "details": [
750
+ "Buttoned, Cross Back",
751
+ "Tailored",
752
+ "Buttoned",
753
+ "Buttoned, Pocket ",
754
+ "Buttoned "
755
+ ],
756
+ "style": [
757
+ "Cropped"
758
+ ]
759
+ },
760
+ "women-sweatersknits-cardigan": {
761
+ "fabricstyle": [
762
+ "Woven",
763
+ "Cable Knitted",
764
+ "Bouclette",
765
+ "Knitted"
766
+ ],
767
+ "pattern": [
768
+ "Floral",
769
+ "Patterned",
770
+ "Geometric",
771
+ "Solid",
772
+ "Strawberry Embroidered",
773
+ "Striped",
774
+ "Crochet"
775
+ ],
776
+ "sleevelength": [
777
+ "Short Sleeve",
778
+ "Long Sleeve"
779
+ ],
780
+ "details": [
781
+ "Ribbed Cut Out ",
782
+ "Fur Detail ",
783
+ "Cut Out ",
784
+ "Buttoned ",
785
+ "Baloon Sleeve ",
786
+ "Buttoned",
787
+ "Pearl Detail ",
788
+ "Zippered ",
789
+ "Accessorized Back Cut out "
790
+ ],
791
+ "style": [
792
+ "Cropped",
793
+ "Crochet",
794
+ "Classic",
795
+ "Long",
796
+ "Oversized",
797
+ "Relaxed"
798
+ ]
799
+ },
800
+ "women-top-top": {
801
+ "fabricstyle": [
802
+ "Slinky Fabric",
803
+ "Chiffon",
804
+ "Metallic",
805
+ "Linen",
806
+ "Cotton",
807
+ "Mesh",
808
+ "Faux Leather",
809
+ "Lace",
810
+ "Woven",
811
+ "Knitted"
812
+ ],
813
+ "pattern": [
814
+ "Polka Dot",
815
+ "Floral",
816
+ "Solid",
817
+ "Star Patterned",
818
+ "Checked",
819
+ "Textured"
820
+ ],
821
+ "sleevelength": [
822
+ "Short Sleeve",
823
+ "Sleeveless",
824
+ "Cap Sleeve",
825
+ "Long Sleeve"
826
+ ],
827
+ "details": [
828
+ "Ribbed, Cut Out ",
829
+ "Ruched ",
830
+ "Ribbed ",
831
+ "Strappy ",
832
+ "Smocked, Puff Sleeve",
833
+ "Spanish Sleeves",
834
+ "Detailed ",
835
+ "Sheer",
836
+ "Balloon Sleeves",
837
+ "Ruched",
838
+ "Buttoned, Ribbed",
839
+ "Ruffle, Sheer",
840
+ "Padded Shoulder ",
841
+ "Smocked",
842
+ "Crochet",
843
+ "Shoulder To Waist Gathered ",
844
+ "Buttoned",
845
+ "Underwire ",
846
+ "Pleated"
847
+ ],
848
+ "style": [
849
+ "Basic",
850
+ "Mini",
851
+ "Cropped",
852
+ "Bandeau",
853
+ "Crochet",
854
+ "Bodycon"
855
+ ]
856
+ },
857
+ "women-top-camistanks": {
858
+ "fabricstyle": [
859
+ "Knitted",
860
+ "Woven"
861
+ ],
862
+ "pattern": [
863
+ "Floral",
864
+ "Solid"
865
+ ],
866
+ "sleevelength": [
867
+ "Sleeveless"
868
+ ],
869
+ "details": [
870
+ "Basic",
871
+ "Basic ",
872
+ "Smocked",
873
+ "Ribbed, Mesh",
874
+ "Buttoned",
875
+ "Ribbed ",
876
+ "Ribbed, Buttoned ",
877
+ "Ribbed"
878
+ ],
879
+ "style": [
880
+ "Basic",
881
+ "Tank",
882
+ "Cropped"
883
+ ]
884
+ },
885
+ "women-top-tshirt": {
886
+ "fabricstyle": [
887
+ "Cotton",
888
+ "Woven"
889
+ ],
890
+ "pattern": [
891
+ "Printed",
892
+ "Acid washed",
893
+ "Solid",
894
+ "Striped"
895
+ ],
896
+ "sleevelength": [
897
+ "Short Sleeve",
898
+ "Sleeveless"
899
+ ],
900
+ "details": [
901
+ "Basic",
902
+ "Stone Embellished",
903
+ "Raw Edge",
904
+ "Filthy Stitch ",
905
+ "Studded"
906
+ ],
907
+ "style": [
908
+ "Basic",
909
+ "Relaxed",
910
+ "Loose"
911
+ ]
912
+ },
913
+ "women-playsuitsjumpsuits-playsuit": {
914
+ "fabricstyle": [
915
+ "Woven",
916
+ "Linen"
917
+ ],
918
+ "details": [
919
+ "Balloon Sleeves",
920
+ "Back Cut Out "
921
+ ],
922
+ "pattern": [
923
+ "Floral",
924
+ "Solid"
925
+ ]
926
+ },
927
+ "women-loungewear-activewear": {
928
+ "fabricstyle": [
929
+ "Woven"
930
+ ],
931
+ "pattern": [
932
+ "Solid"
933
+ ],
934
+ "details": [
935
+ "Elastic Waist, Pocket "
936
+ ],
937
+ "style": [
938
+ "Straight Leg"
939
+ ]
940
+ },
941
+ "women-bottom-shorts": {
942
+ "fabricstyle": [
943
+ "Denim",
944
+ "Linen",
945
+ "Cotton",
946
+ "Faux Leather",
947
+ "Woven",
948
+ "Tweed"
949
+ ],
950
+ "pattern": [
951
+ "Floral",
952
+ "Solid",
953
+ "Striped",
954
+ "Embroderied",
955
+ "Checked"
956
+ ],
957
+ "details": [
958
+ "Pocket detail",
959
+ "Belt Detail",
960
+ "Pleated ",
961
+ "Drawstring",
962
+ "Elastic Waist, Drawstring",
963
+ "Drawstring, Pocket detail",
964
+ "Elastic Waist",
965
+ "Belt",
966
+ "Pocket ",
967
+ "Drawstring, Pocket",
968
+ "Button detail, Double Layered",
969
+ "Elastic Waist, Ruffle",
970
+ "Ribbed"
971
+ ]
972
+ },
973
+ "women-playsuitsjumpsuits-jumpsuit": {
974
+ "fabricstyle": [
975
+ "Denim",
976
+ "Woven"
977
+ ],
978
+ "details": [
979
+ "Buttoned Ribbon Belt ",
980
+ "Pleated",
981
+ "Buttoned"
982
+ ],
983
+ "pattern": [
984
+ "Solid"
985
+ ]
986
+ },
987
+ "women-loungewear-joggers": {
988
+ "fabricstyle": [
989
+ "Woven",
990
+ "Knitted"
991
+ ],
992
+ "pattern": [
993
+ "Washed",
994
+ "Solid"
995
+ ],
996
+ "details": [
997
+ "Elastic Waist, Pocket",
998
+ "Pocket Detail",
999
+ "Drawstring",
1000
+ "Elastic Waist",
1001
+ "Slit "
1002
+ ],
1003
+ "style": [
1004
+ "Basic",
1005
+ "Regular Fit",
1006
+ "Cargo",
1007
+ "Straight Leg",
1008
+ "Wide Leg"
1009
+ ]
1010
+ },
1011
+ "women-loungewear-hoodie": {
1012
+ "fabricstyle": [
1013
+ "Woven"
1014
+ ],
1015
+ "pattern": [
1016
+ "Solid"
1017
+ ],
1018
+ "sleevelength": [
1019
+ "Long Sleeve"
1020
+ ],
1021
+ "details": [
1022
+ "Hooded Ruched Bottom ",
1023
+ "Zippered, Stitch Details"
1024
+ ],
1025
+ "style": [
1026
+ "Cropped"
1027
+ ]
1028
+ },
1029
+ "women-sweatersknits-blouse": {
1030
+ "fabricstyle": [
1031
+ "Mesh"
1032
+ ],
1033
+ "pattern": [
1034
+ "Crochet"
1035
+ ],
1036
+ "sleevelength": [
1037
+ "Long Sleeve"
1038
+ ],
1039
+ "details": [
1040
+ "Mesh"
1041
+ ]
1042
+ },
1043
+ "women-swimwear-bikinisets": {
1044
+ "fabricstyle": [
1045
+ "Knitted"
1046
+ ],
1047
+ "pattern": [
1048
+ "Tie Dye",
1049
+ "Solid",
1050
+ "Ombre"
1051
+ ],
1052
+ "details": [
1053
+ "Tie Side",
1054
+ "Strappy",
1055
+ "Crochet, Tie Side"
1056
+ ],
1057
+ "style": [
1058
+ "Plunge",
1059
+ "Triangle",
1060
+ "Bandeau"
1061
+ ]
1062
+ },
1063
+ "women-swimwear-onepieces": {
1064
+ "pattern": [
1065
+ "Solid"
1066
+ ],
1067
+ "details": [
1068
+ "Asymmetric, Strappy",
1069
+ "Strappy",
1070
+ "Cut out"
1071
+ ],
1072
+ "style": [
1073
+ "One Shoulder"
1074
+ ]
1075
+ },
1076
+ "women-accessories-bags": {
1077
+ "fabricstyle": [
1078
+ "Canvas",
1079
+ "Denim"
1080
+ ],
1081
+ "details": [
1082
+ "2-handle"
1083
+ ],
1084
+ "pattern": [
1085
+ "Solid"
1086
+ ]
1087
+ },
1088
+ "women-dress-dress": {
1089
+ "fabricstyle": [
1090
+ "Woven"
1091
+ ],
1092
+ "pattern": [
1093
+ "Solid"
1094
+ ],
1095
+ "sleevelength": [
1096
+ "Short Sleeve"
1097
+ ],
1098
+ "details": [
1099
+ "Puff Sleeves"
1100
+ ]
1101
+ },
1102
+ "women-outwear-kimonos": {
1103
+ "fabricstyle": [
1104
+ "Woven"
1105
+ ],
1106
+ "pattern": [
1107
+ "Embroidered"
1108
+ ],
1109
+ "sleevelength": [
1110
+ "Long Sleeve"
1111
+ ],
1112
+ "style": [
1113
+ "Long"
1114
+ ]
1115
+ }
1116
+ }}
color_config.json ADDED
@@ -0,0 +1,90 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "color_mapping":
3
+ {
4
+ "white": [
5
+ "Dusty White",
6
+ "White"
7
+ ],
8
+ "blue": [
9
+ "Baby Blue",
10
+ "Cerulean Blue",
11
+ "Cobalt Blue",
12
+ "Cornflower Blue",
13
+ "Ice Blue",
14
+ "Maya Blue",
15
+ "Midnight Blue",
16
+ "Moroccan Blue",
17
+ "Navy Blue",
18
+ "Oxford Blue",
19
+ "Powder Blue"
20
+ ],
21
+ "denim": [
22
+ "Dark Blue Denim",
23
+ "Light-Mid Blue Denim",
24
+ "Light Blue Denim",
25
+ "Mid Blue Denim"
26
+ ],
27
+ "grey": [
28
+ "Charcoal Grey",
29
+ "Dark Grey",
30
+ "Grey",
31
+ "Light Grey",
32
+ "Silver Grey",
33
+ "Slate Grey"
34
+ ],
35
+ "orange": [
36
+ "Bright Orange",
37
+ "Pumpkin Orange",
38
+ "Pale Orange"
39
+ ],
40
+ "pink": [
41
+ "Blush Pink",
42
+ "Bright Pink",
43
+ "Carnation Pink",
44
+ "Dusty Rose Pink",
45
+ "Magenta Pink",
46
+ "Neon Pink",
47
+ "Powder Pink"
48
+ ],
49
+ "natural": [
50
+ "Beige Natural",
51
+ "Cream Natural",
52
+ "Ivory Natural",
53
+ "Natural",
54
+ "Oatmeal Natural",
55
+ "Stone Natural",
56
+ "Tan Natural"
57
+ ],
58
+ "yellow": [
59
+ "Amber Yellow",
60
+ "Lemon Yellow"
61
+ ],
62
+ "multicolor": ["Multicolor"],
63
+ "brown": [
64
+ "Beaver Brown",
65
+ "Camel Brown",
66
+ "Chestnut Brown",
67
+ "Coffee Brown",
68
+ "Dark Mocha Brown",
69
+ "Mocha Brown",
70
+ "Walnut Brown"
71
+ ],
72
+ "green": ["Emerald Green",
73
+ "Forest Green",
74
+ "Green",
75
+ "Khaki Green",
76
+ "Mint Green",
77
+ "Olive Green",
78
+ "Pine Green",
79
+ "Sacramento Green",
80
+ "Sage Green",
81
+ "Lime Green"],
82
+ "purple": ["Amethyst Purple",
83
+ "Lavender Purple",
84
+ "Mauve Purple",
85
+ "Periwinkle Purple",
86
+ "Lilac Purple",
87
+ "Electric Purple"],
88
+ "red": ["Brick Red", "Cherry Red","Red"]}
89
+
90
+ }
requirements.txt ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ transformers
2
+ torch
3
+ openai
4
+ face_recognition
5
+ torchvision