smagen10 commited on
Commit
2759de1
·
1 Parent(s): 82df0c0

utils added

Browse files
utils/__pycache__/advisor.cpython-312.pyc ADDED
Binary file (501 Bytes). View file
 
utils/__pycache__/bg_removal.cpython-312.pyc ADDED
Binary file (1.12 kB). View file
 
utils/__pycache__/detector.cpython-312.pyc ADDED
Binary file (1.96 kB). View file
 
utils/__pycache__/detector.cpython-39.pyc ADDED
Binary file (825 Bytes). View file
 
utils/advisor.py ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ from models.llm import StyleSavvy
2
+
3
+ advisor = StyleSavvy()
4
+
5
+ def get_advice(items, body_type, face_shape, gender,occasion):
6
+ return advisor.advise(items, body_type, face_shape, gender, occasion)
7
+
utils/bg_removal.py ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os, requests
2
+ from io import BytesIO
3
+ from PIL import Image
4
+ from dotenv import load_dotenv
5
+
6
+ load_dotenv()
7
+
8
+ API_KEY = os.getenv("REMOVE_BG_API_KEY")
9
+ ENDPOINT = "https://api.remove.bg/v1.0/removebg"
10
+
11
+ def remove_background(image_bytes: bytes) -> Image.Image:
12
+ resp = requests.post(
13
+ ENDPOINT,
14
+ files ={"image_file": ("image.jpg", image_bytes, "image/jpeg")},
15
+ data = {"size": "auto"},
16
+ headers = {"X-Api-Key": API_KEY},
17
+ )
18
+ resp.raise_for_status()
19
+ return Image.open(BytesIO(resp.content))
20
+
utils/detector.py ADDED
@@ -0,0 +1,59 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ from io import BytesIO
3
+ from PIL import Image
4
+ from models.vision import VisionModel
5
+ from utils.bg_removal import remove_background
6
+
7
+ vision = VisionModel()
8
+ FASHION_LABELS = {
9
+ "shirt", "t-shirt", "blouse", "tank top", "sweater", "hoodie", "jacket",
10
+ "coat", "overcoat", "raincoat", "windbreaker", "cardigan", "blazer",
11
+ "pants", "jeans", "shorts", "leggings", "tights", "skirt", "dress",
12
+ "suit", "jumpsuit", "romper", "vest", "sports bra", "tracksuit",
13
+ "belt", "tie", "scarf", "hat", "cap", "gloves", "socks",
14
+ "shoe", "sneakers", "boots", "sandals", "heels",
15
+ "watch", "necklace", "bracelet", "earrings", "ring",
16
+ "backpack", "handbag", "purse", "wallet"
17
+ }
18
+
19
+ def detect_clothing(image_input, do_bg_remove: bool = False):
20
+ # 1) Load into a PIL.Image if it's a filepath
21
+ if isinstance(image_input, str):
22
+ img = Image.open(image_input)
23
+ else:
24
+ img = image_input
25
+
26
+ # 2) Optionally remove background (works on bytes)
27
+ if do_bg_remove:
28
+ buf = BytesIO()
29
+ img.convert("RGB").save(buf, format="JPEG")
30
+ img_bytes = buf.getvalue()
31
+ img = remove_background(img_bytes)
32
+ else:
33
+ # ensure you drop any alpha channel
34
+ img = img.convert("RGB")
35
+
36
+ # 3) Run detection
37
+ raw_detections = vision.detect(img)
38
+
39
+ # 4) Filter and deduplicate
40
+ filtered = {}
41
+ for det in raw_detections:
42
+ label = det["label"].lower()
43
+ if label in FASHION_LABELS:
44
+ # Only keep the first or highest score if multiple detected
45
+ if label not in filtered or det["score"] > filtered[label]["score"]:
46
+ filtered[label] = {
47
+ "label": label,
48
+ "score": det["score"],
49
+ "box": det.get("box", [])
50
+ }
51
+
52
+ # 5) Return dict or fallback if empty
53
+ if not filtered:
54
+ return {"outfit": {"label": "outfit", "score": 1.0, "box": []}}
55
+
56
+ return filtered
57
+
58
+
59
+
utils/test_detector.py ADDED
@@ -0,0 +1,49 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # test_detector.py
2
+
3
+ from detector import detect_clothing
4
+ from PIL import Image, ImageDraw
5
+ import os
6
+
7
+ def visualize_and_print(image_path, do_bg_remove=False, output_dir="vis"):
8
+ # Ensure output folder exists
9
+ os.makedirs(output_dir, exist_ok=True)
10
+
11
+ img = Image.open(image_path).convert("RGB")
12
+ print(f"\n--- Testing {os.path.basename(image_path)} (bg_remove={do_bg_remove}) ---")
13
+
14
+ # Run your detector
15
+ dets = detect_clothing(img, do_bg_remove=do_bg_remove)
16
+ if not dets:
17
+ print("No detections!")
18
+ return
19
+
20
+ # Print raw detections
21
+ # Print raw detections
22
+ for i, d in enumerate(dets.values(), 1):
23
+ lbl = d["label"]
24
+ scr = d["score"]
25
+ box = d.get("box", [])
26
+ print(f" {i}. {lbl:12s} @ {scr:.2f} → {box}")
27
+
28
+ # Draw boxes
29
+ vis = img.copy()
30
+ draw = ImageDraw.Draw(vis)
31
+ for d in dets.values():
32
+ if d.get("box"):
33
+ x0, y0, x1, y1 = d["box"]
34
+ draw.rectangle([x0, y0, x1, y1], outline="red", width=2)
35
+ draw.text((x0, y0 - 10), f"{d['label']}:{d['score']:.2f}", fill="red")
36
+ # Save visualization
37
+ out_path = os.path.join(output_dir, os.path.basename(image_path))
38
+ vis.save(out_path)
39
+ print(f" Visualization saved to {out_path}")
40
+
41
+ if __name__ == "__main__":
42
+ # List your test images here
43
+ samples = [
44
+ "/Users/tanzimfarhan/Desktop/Python/Codes/SLU/CS5930/FinalProject/StyleSavvy/images/casual.jpg",
45
+ "/Users/tanzimfarhan/Desktop/Python/Codes/SLU/CS5930/FinalProject/StyleSavvy/images/WomenCasual.jpg",
46
+ ]
47
+ for img_path in samples:
48
+ visualize_and_print(img_path, do_bg_remove=False)
49
+ # visualize_and_print(img_path, do_bg_remove=True)
utils/test_llm.py ADDED
@@ -0,0 +1,193 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # # test_llm.py
2
+ # """
3
+ # Test harness for StyleSavvy LLM prompts.
4
+ # Defines multiple prompt templates and evaluates the generated outputs,
5
+ # checking for the expected number of bullet-point style tips.
6
+ # """
7
+ # from models.llm import StyleSavvy
8
+
9
+ # # Variant prompt templates with placeholders
10
+ # PROMPT_TEMPLATES = {
11
+ # "occasion_driven": (
12
+ # "You are an expert fashion stylist. A client is preparing for {occasion}. "
13
+ # "They have a {body_type}-shaped body and a {face_shape} face. They’re currently wearing: {items}. "
14
+ # "Give 3 to 5 *distinct* style tips focused on making them look their best at the event. "
15
+ # "Make the suggestions relevant to the setting, weather, and formality of the occasion. "
16
+ # "Avoid repeating any advice."
17
+ # ),
18
+
19
+ # "function_based": (
20
+ # "You're advising someone with a {body_type} build and {face_shape} face. "
21
+ # "They're attending a {occasion} and are wearing {items}. "
22
+ # "Suggest 3–5 concise fashion improvements or enhancements. "
23
+ # "Each suggestion should be unique and tailored to the event. "
24
+ # "Include practical choices for color, layering, accessories, or footwear. "
25
+ # "Avoid repeating words or phrases."
26
+ # ),
27
+
28
+ # "intent_style": (
29
+ # "Act as a high-end personal stylist. Your client has a {body_type} body shape and a {face_shape} face. "
30
+ # "They're going to a {occasion} and are wearing {items}. "
31
+ # "Write 3 to 5 brief but powerful styling suggestions to elevate their look. "
32
+ # "Focus on intent—what feeling or impression each style choice creates for the event."
33
+ # ),
34
+ # }
35
+
36
+
37
+ # # Test parameters
38
+ # BODY_TYPE = "Slim"
39
+ # FACE_SHAPE = "Round"
40
+ # OCCASION = "Rooftop Evening Party"
41
+ # ITEMS = ["shirt", "jeans", "jacket","shoes"]
42
+
43
+ # if __name__ == "__main__":
44
+ # advisor = StyleSavvy()
45
+
46
+ # for name, template in PROMPT_TEMPLATES.items():
47
+ # # Build prompt by replacing placeholders
48
+ # prompt = template.format(
49
+ # body_type=BODY_TYPE,
50
+ # face_shape=FACE_SHAPE,
51
+ # occasion=OCCASION,
52
+ # items=", ".join(ITEMS)
53
+ # )
54
+ # print(f"=== Testing template: {name} ===")
55
+ # print("Prompt:")
56
+ # print(prompt)
57
+
58
+ # # Generate output (use only supported args)
59
+ # result = advisor.pipe(
60
+ # prompt,
61
+ # max_length=advisor.max_length,
62
+ # early_stopping=True,
63
+ # do_sample=False
64
+ # )[0]["generated_text"].strip()
65
+
66
+ # print("Generated output:")
67
+ # print(result)
68
+
69
+ # # Extract bullet lines
70
+ # bullets = [ln for ln in result.splitlines() if ln.strip().startswith("- ")]
71
+ # print(f"Number of bullets detected: {len(bullets)}")
72
+ # for i, b in enumerate(bullets, start=1):
73
+ # print(f" {i}. {b}")
74
+ # print("" + "-"*40)
75
+
76
+
77
+ # test_llm.py
78
+ """
79
+ Test harness for StyleSavvy LLM prompts.
80
+ Evaluates multiple prompt templates and parses the generated outputs into distinct tips.
81
+ """
82
+
83
+ from models.llm import StyleSavvy
84
+
85
+ # Variant prompt templates with placeholders
86
+ # PROMPTS = {
87
+ # "direct_instruction": (
88
+ # "You are a professional fashion stylist. A client with a {body_type}-shaped body "
89
+ # "and {face_shape} face is preparing for {occasion}. They are currently wearing: {items}. "
90
+ # "Give exactly five distinct styling tips to improve their outfit. "
91
+ # "Each tip should be concise, actionable, and start on a new line."
92
+ # ),
93
+ # "category_expansion": (
94
+ # "As a high-end fashion advisor, provide five styling tips for a {body_type}-shaped person "
95
+ # "with a {face_shape} face attending {occasion}. They are wearing {items}. "
96
+ # "Offer one tip each for silhouette, color, accessories, footwear, and layering, "
97
+ # "each on its own line."
98
+ # ),
99
+ # "event_aesthetic": (
100
+ # "Imagine curating the perfect outfit for a {body_type}-shaped individual with a {face_shape} face "
101
+ # "at {occasion}. They are wearing {items}. Suggest 5 ways to enhance their style, "
102
+ # "focusing on event-appropriate aesthetics. Separate each tip with a newline."
103
+ # ),
104
+ # "fashion_editor": (
105
+ # "As a fashion editor, outline five unique styling tips for a {body_type}-shaped reader with a {face_shape} face "
106
+ # "attending {occasion}. They wear {items}. Each recommendation should reflect expertise and relevance. "
107
+ # "List each tip on a new line."
108
+ # ),
109
+ # "influencer_style": (
110
+ # "You’re an influencer giving sharp styling advice. A follower with a {body_type} body and {face_shape} face "
111
+ # "is going to {occasion}, wearing {items}. Reply with five snappy, modern style tips, "
112
+ # "each on its own line."
113
+ # ),
114
+ # }
115
+
116
+ PROMPTS = {
117
+ "direct_instruction": (
118
+ "You are a world-renowned fashion stylist celebrated for your bold creativity and attention to detail. "
119
+ "Your {gender} client has a {body_type}-shaped silhouette and a {face_shape} face, preparing for the {occasion}. "
120
+ "They’re wearing {items}. In vivid, sensory-rich language, provide one transformative styling recommendation that considers the event’s ambiance, lighting, and dress code. "
121
+ "Use dynamic adjectives and actionable insight to elevate their entire look."
122
+ ),
123
+ "category_expansion": (
124
+ "As a top-tier fashion advisor, craft one impactful styling suggestion for a {gender} individual with a {body_type} body "
125
+ "and {face_shape} face attending the {occasion}. They have on {items}. "
126
+ "Highlight a strategic enhancement in silhouette, color scheme, accessory choice, or footwear to elevate their look."
127
+ ),
128
+ "event_aesthetic": (
129
+ "Imagine you are curating an immersive style experience for a {gender} attendee with a {body_type} silhouette and {face_shape} face at the {occasion}. "
130
+ "They’re currently wearing {items}. Provide one highly descriptive recommendation that harmonizes fabric textures, color temperature, silhouette, and accessory accents with the event’s specific ambiance, lighting conditions, and seasonal atmosphere."
131
+ ),
132
+ "fashion_editor": (
133
+ "You are the Editor-in-Chief of a prestigious fashion publication. Advise a {gender} trendsetter with a {body_type} frame and {face_shape} face attending the {occasion}, "
134
+ "currently in {items}. Offer one magazine-cover-worthy styling tip—highlight a trending color palette, editorial-worthy silhouette, and innovative accessory placement that will resonate with a discerning audience."
135
+ ),
136
+ "influencer_style": (
137
+ "As a cutting-edge style influencer with millions of followers, recommend one eye-catching flair tip for a {gender} follower with a {body_type} physique and {face_shape} face, "
138
+ "heading to the {occasion} in {items}. Frame it as a social-media-caption-ready moment: mention a statement accessory, bold color pop, or texture twist that will go viral."
139
+ ),
140
+ "seasonal_trend": (
141
+ "As a seasonal style expert specializing in spring/summer trends, guide a {gender} individual with a {body_type} shape and {face_shape} face preparing for the {occasion}. "
142
+ "They currently wear {items}. Provide one tip incorporating current seasonal motifs—think floral prints, breathable linens, or eco-friendly fabrics—that elevates their ensemble."
143
+ ),
144
+ }
145
+
146
+
147
+ # Test parameters
148
+ BODY_TYPE = "Slim"
149
+ FACE_SHAPE = "SQUARE"
150
+ OCCASION = "BEACH PARTY"
151
+ ITEMS = ["jeans", "jacket", "shoes",'shirt']
152
+ GENDER = "Male"
153
+
154
+ if __name__ == "__main__":
155
+ advisor = StyleSavvy()
156
+
157
+ for name, template in PROMPTS.items():
158
+ print(f"=== Testing template: {name} ===")
159
+
160
+ # Build prompt
161
+ prompt = template.format(
162
+ body_type=BODY_TYPE,
163
+ face_shape=FACE_SHAPE,
164
+ occasion=OCCASION,
165
+ gender = GENDER,
166
+ items=", ".join(ITEMS)
167
+
168
+ )
169
+ print("Prompt:\n" + prompt)
170
+
171
+ # Generate response
172
+ result = advisor.pipe(
173
+ prompt,
174
+ max_length=advisor.max_length,
175
+ early_stopping=True,
176
+ num_beams=4,
177
+ no_repeat_ngram_size=3,
178
+ do_sample=False)[0]["generated_text"].strip()
179
+
180
+ print("\nRaw generated output:\n" + result)
181
+
182
+ # Parse into tips (bullets or sentence)
183
+ lines = result.splitlines()
184
+ tips = [ln.strip("-*0123456789. ").strip() for ln in lines if ln.strip()]
185
+ if len(tips) < 3:
186
+ # fallback to sentence split
187
+ tips = [p.strip() for p in result.split(".") if p.strip()]
188
+ tips = list(dict.fromkeys(tips)) # remove duplicates
189
+
190
+ print(f"\n💡 Parsed {len(tips)} style tips:")
191
+ for i, tip in enumerate(tips[:5], 1):
192
+ print(f"{i}. {tip}")
193
+ print("-" * 40)