selinazarzour commited on
Commit
dadf8b4
·
1 Parent(s): b5a783b

Added the shopping automation logic in a new tab

Browse files
Files changed (3) hide show
  1. README.md +57 -16
  2. app.py +115 -1
  3. requirements.txt +1 -0
README.md CHANGED
@@ -8,11 +8,33 @@ sdk_version: 5.42.0
8
  app_file: app.py
9
  pinned: false
10
  ---
11
-
12
- # 🤖 AI-Powered Virtual Try-On
13
 
14
  A portfolio-ready, full-stack AI fashion assistant and virtual try-on system. Combines computer vision, conversational AI, and web automation to deliver style advice, outfit analysis, and shopping recommendations—all in one interactive web app.
15
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
16
  ## 🚀 Features
17
  - **Virtual Try-On:** Upload clothing and avatar images to generate realistic try-on results.
18
  - **AI Fashion Analysis:** Get style advice and outfit analysis using BLIP and CLIP models.
@@ -26,24 +48,43 @@ A portfolio-ready, full-stack AI fashion assistant and virtual try-on system. Co
26
  - **AI Models:** BLIP, CLIP, TinyLlama (all open-source, loaded on demand)
27
  - **Automation:** Playwright for web scraping and product search
28
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
29
  ## 🛠️ Setup & Deployment
30
  1. All dependencies are listed in `requirements.txt`.
31
  2. The backend Flask server is started automatically by `app.py`.
32
  3. The Gradio interface is the entry point for Hugging Face Spaces.
33
 
34
- ## 💡 Usage
35
- - Upload a fashion image to get instant AI-powered analysis and advice.
36
- - Chat with the AI assistant for style tips and outfit suggestions.
37
- - Use the shopping automation to discover and compare similar products online.
38
-
39
- ## 🌐 Public Demo
40
- Deploy this project on [Hugging Face Spaces](https://huggingface.co/spaces) for a live, shareable demo. Free CPU and GPU options available.
41
-
42
- ## 📄 License
43
- Open-source, for educational and portfolio use. See project root for details.
44
-
45
- ---
46
 
47
- **For more details, see the full documentation and quick start guides in the main project repository.**
 
48
 
49
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
8
  app_file: app.py
9
  pinned: false
10
  ---
11
+ # AI Virtual Try-On & Fashion Advisor (Hugging Face Space)
 
12
 
13
  A portfolio-ready, full-stack AI fashion assistant and virtual try-on system. Combines computer vision, conversational AI, and web automation to deliver style advice, outfit analysis, and shopping recommendations—all in one interactive web app.
14
 
15
+ ## Features
16
+
17
+ ### 1. Try-On & Analysis
18
+ - **Upload Clothing Image & Avatar Image:**
19
+ - Upload two images: one of a clothing item and one of an avatar/person.
20
+ - **AI Try-On Generation:**
21
+ - Uses the [try-on-diffusion API](https://rapidapi.com/hlbq/api/try-on-diffusion/) to generate a virtual try-on result.
22
+ - **BLIP/CLIP AI Analysis:**
23
+ - Automatically analyzes the generated try-on image using BLIP for captioning and fashion prompts.
24
+ - **LLM Fashion Advice:**
25
+ - Provides detailed, context-aware fashion advice using TinyLlama LLM, based on the AI analysis.
26
+ - **All results (image, analysis, advice) are displayed together.**
27
+
28
+ ### 2. Chatbot (TinyLlama LLM)
29
+ - **Fashion Chatbot:**
30
+ - Chat with an AI stylist powered by TinyLlama.
31
+ - The chatbot always has context from your latest try-on and analysis, so you can ask about "this outfit" or "these colors" and get relevant answers.
32
+
33
+ ### 3. Find Similar
34
+ - **Upload any try-on or fashion image.**
35
+ - **Get recommendations for similar outfits, complementary accessories, and alternative colors.**
36
+ - **Suggested stores are included in the recommendations.**
37
+
38
  ## 🚀 Features
39
  - **Virtual Try-On:** Upload clothing and avatar images to generate realistic try-on results.
40
  - **AI Fashion Analysis:** Get style advice and outfit analysis using BLIP and CLIP models.
 
48
  - **AI Models:** BLIP, CLIP, TinyLlama (all open-source, loaded on demand)
49
  - **Automation:** Playwright for web scraping and product search
50
 
51
+ ## How It Works
52
+ - All AI models (BLIP, CLIP, TinyLlama) are loaded and run in the backend.
53
+ - The try-on image is generated via an external API (RapidAPI key required).
54
+ - The app is organized into tabs for a clean, modern user experience.
55
+
56
+ ## Requirements
57
+ - Python 3.8+
58
+ - `gradio`, `transformers`, `torch`, `Pillow`, `requests`
59
+ - A valid RapidAPI key for try-on-diffusion (replace in `app.py` if needed)
60
+
61
+ ## Usage
62
+ 1. **Clone this repo and open in Hugging Face Spaces or run locally.**
63
+ 2. **Install requirements:**
64
+ ```bash
65
+ pip install -r requirements.txt
66
+ ```
67
+ 3. **Run the app:**
68
+ ```bash
69
+ python app.py
70
+ ```
71
+ 4. **Use the web UI:**
72
+ - Try-On & Analysis: Upload images, generate try-on, get analysis/advice.
73
+ - Chatbot: Ask fashion questions with context.
74
+ - Find Similar: Get recommendations for similar outfits.
75
+
76
  ## 🛠️ Setup & Deployment
77
  1. All dependencies are listed in `requirements.txt`.
78
  2. The backend Flask server is started automatically by `app.py`.
79
  3. The Gradio interface is the entry point for Hugging Face Spaces.
80
 
81
+ ## Credits
82
+ - BLIP: [Salesforce BLIP](https://huggingface.co/Salesforce/blip-image-captioning-base)
83
+ - CLIP: [OpenAI CLIP](https://huggingface.co/openai/clip-vit-base-patch32)
84
+ - LLM: [TinyLlama](https://huggingface.co/TinyLlama/TinyLlama-1.1B-Chat-v1.0)
85
+ - Try-On API: [try-on-diffusion](https://rapidapi.com/hlbq/api/try-on-diffusion/)
 
 
 
 
 
 
 
86
 
87
+ ## License
88
+ MIT
89
 
90
+ ---
app.py CHANGED
@@ -130,7 +130,6 @@ def analyze_fashion(image):
130
  advice = llm_advise(sys_prompt, user_msg)
131
  return advice
132
 
133
-
134
  # --- Try-On API Integration ---
135
  import requests
136
  def tryon_api(clothing_img, avatar_img):
@@ -153,6 +152,115 @@ def tryon_api(clothing_img, avatar_img):
153
  return Image.open(io.BytesIO(response.content))
154
  else:
155
  raise Exception('Try-on generation failed: ' + response.text)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
156
 
157
  # --- Gradio UI: Try-On Only ---
158
  with gr.Blocks() as demo:
@@ -232,5 +340,11 @@ with gr.Blocks() as demo:
232
  sim_btn = gr.Button("Find Similar Outfits")
233
  sim_output = gr.Textbox(label="Similar Outfits & Recommendations")
234
  sim_btn.click(recommend_similar, inputs=sim_input, outputs=sim_output)
 
 
 
 
 
 
235
 
236
  demo.launch()
 
130
  advice = llm_advise(sys_prompt, user_msg)
131
  return advice
132
 
 
133
  # --- Try-On API Integration ---
134
  import requests
135
  def tryon_api(clothing_img, avatar_img):
 
152
  return Image.open(io.BytesIO(response.content))
153
  else:
154
  raise Exception('Try-on generation failed: ' + response.text)
155
+
156
+ import asyncio
157
+ import re
158
+ try:
159
+ from playwright.async_api import async_playwright
160
+ except ImportError:
161
+ async_playwright = None
162
+
163
+ FASHION_SITES = {
164
+ 'zara': {
165
+ 'url': 'https://www.zara.com/us/en/search',
166
+ 'search_param': 'searchTerm',
167
+ 'selectors': {
168
+ 'products': '.product-item',
169
+ 'title': '.product-link',
170
+ 'price': '.price',
171
+ 'image': '.media-image img',
172
+ 'link': '.product-link'
173
+ }
174
+ },
175
+ 'hm': {
176
+ 'url': 'https://www2.hm.com/en_us/search-results.html',
177
+ 'search_param': 'q',
178
+ 'selectors': {
179
+ 'products': '.item-link',
180
+ 'title': '.item-heading',
181
+ 'price': '.item-price',
182
+ 'image': '.item-image img',
183
+ 'link': '.item-link'
184
+ }
185
+ },
186
+ 'asos': {
187
+ 'url': 'https://www.asos.com/us/search/',
188
+ 'search_param': 'q',
189
+ 'selectors': {
190
+ 'products': '[data-testid="product-tile"]',
191
+ 'title': '[data-testid="product-title"]',
192
+ 'price': '[data-testid="current-price"]',
193
+ 'image': 'img',
194
+ 'link': 'a'
195
+ }
196
+ }
197
+ }
198
+
199
+ async def search_fashion_items(query, max_results=3):
200
+ results = []
201
+ if async_playwright is None:
202
+ return results
203
+ try:
204
+ async with async_playwright() as p:
205
+ browser = await p.chromium.launch(headless=True)
206
+ context = await browser.new_context(
207
+ user_agent='Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'
208
+ )
209
+ for site_name, site_config in FASHION_SITES.items():
210
+ try:
211
+ page = await context.new_page()
212
+ search_url = f"{site_config['url']}?{site_config['search_param']}={query}"
213
+ await page.goto(search_url, wait_until='networkidle', timeout=10000)
214
+ await page.wait_for_timeout(2000)
215
+ products = await page.query_selector_all(site_config['selectors']['products'])
216
+ site_results = []
217
+ for product in products[:max_results]:
218
+ try:
219
+ title_elem = await product.query_selector(site_config['selectors']['title'])
220
+ price_elem = await product.query_selector(site_config['selectors']['price'])
221
+ image_elem = await product.query_selector(site_config['selectors']['image'])
222
+ link_elem = await product.query_selector(site_config['selectors']['link'])
223
+ title = await title_elem.inner_text() if title_elem else 'N/A'
224
+ price = await price_elem.inner_text() if price_elem else 'N/A'
225
+ image_src = await image_elem.get_attribute('src') if image_elem else ''
226
+ link_href = await link_elem.get_attribute('href') if link_elem else ''
227
+ title = title.strip()[:100]
228
+ price = re.sub(r'[^\\d.,$€£]', '', price) if price != 'N/A' else 'N/A'
229
+ if link_href and not link_href.startswith('http'):
230
+ base_url = f"https://{site_name}.com" if site_name != 'hm' else 'https://www2.hm.com'
231
+ link_href = base_url + link_href
232
+ site_results.append({
233
+ 'title': title,
234
+ 'price': price,
235
+ 'image': image_src,
236
+ 'link': link_href,
237
+ 'store': site_name.upper(),
238
+ 'query': query
239
+ })
240
+ except Exception:
241
+ pass
242
+ results.extend(site_results)
243
+ await page.close()
244
+ except Exception:
245
+ pass
246
+ await browser.close()
247
+ except Exception:
248
+ pass
249
+ return results
250
+
251
+ def shopping_search_sync(query):
252
+ loop = asyncio.new_event_loop()
253
+ asyncio.set_event_loop(loop)
254
+ try:
255
+ results = loop.run_until_complete(search_fashion_items(query, max_results=3))
256
+ finally:
257
+ loop.close()
258
+ if not results:
259
+ return "No products found. Try a different keyword."
260
+ out = ""
261
+ for r in results:
262
+ out += f"\n**{r['title']}**\nStore: {r['store']}\nPrice: {r['price']}\n[View Product]({r['link']})\n\n"
263
+ return out
264
 
265
  # --- Gradio UI: Try-On Only ---
266
  with gr.Blocks() as demo:
 
340
  sim_btn = gr.Button("Find Similar Outfits")
341
  sim_output = gr.Textbox(label="Similar Outfits & Recommendations")
342
  sim_btn.click(recommend_similar, inputs=sim_input, outputs=sim_output)
343
+
344
+ with gr.Tab("Shopping Automation"):
345
+ shop_query = gr.Textbox(label="Describe the item or keywords to search (e.g. 'black dress', 'summer shirt')")
346
+ shop_btn = gr.Button("Search Fashion Stores")
347
+ shop_results = gr.Markdown(label="Shopping Results")
348
+ shop_btn.click(shopping_search_sync, inputs=shop_query, outputs=shop_results)
349
 
350
  demo.launch()
requirements.txt CHANGED
@@ -46,3 +46,4 @@ typing-inspection==0.4.1
46
  typing_extensions==4.14.0
47
  urllib3==2.5.0
48
  Werkzeug==3.1.3
 
 
46
  typing_extensions==4.14.0
47
  urllib3==2.5.0
48
  Werkzeug==3.1.3
49
+ playwright