Hashii1729 commited on
Commit
2805777
·
1 Parent(s): f8b306b

Add structured JSON analysis functionality: implement new API endpoints for detailed fashion analysis and enhance documentation

Browse files
Files changed (2) hide show
  1. JSON_API_DOCUMENTATION.md +368 -0
  2. fast.py +252 -1
JSON_API_DOCUMENTATION.md ADDED
@@ -0,0 +1,368 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # JSON API Documentation
2
+
3
+ This document describes the JSON-structured API endpoints for the Vestiq Fashion Analysis System.
4
+
5
+ ## Overview
6
+
7
+ The Vestiq API now provides structured JSON responses for fashion analysis, making it easy to integrate with other applications and process results programmatically.
8
+
9
+ ## Base URL
10
+
11
+ ```
12
+ http://localhost:7861
13
+ ```
14
+
15
+ ## Authentication
16
+
17
+ No authentication required for current version.
18
+
19
+ ## Content Types
20
+
21
+ - **Request**: `multipart/form-data` (for image uploads)
22
+ - **Response**: `application/json`
23
+
24
+ ## API Endpoints
25
+
26
+ ### 1. Health Check
27
+
28
+ **GET** `/health`
29
+
30
+ Check the health status of the API and models.
31
+
32
+ **Response:**
33
+ ```json
34
+ {
35
+ "status": "healthy",
36
+ "models": "loaded",
37
+ "device": "cpu"
38
+ }
39
+ ```
40
+
41
+ ### 2. Detailed JSON Analysis
42
+
43
+ **POST** `/analyze-json`
44
+
45
+ Analyze an uploaded image and return comprehensive structured JSON response.
46
+
47
+ **Request:**
48
+ - Method: `POST`
49
+ - Content-Type: `multipart/form-data`
50
+ - Body: Form data with `file` field containing the image
51
+
52
+ **Response:**
53
+ ```json
54
+ {
55
+ "structured_analysis": {
56
+ "upper_garment": {
57
+ "type": "Floral midi dress",
58
+ "color": "Navy blue base with white and pink floral print",
59
+ "material": "Lightweight cotton or cotton blend",
60
+ "features": "Short sleeves, round neckline, fitted bodice with A-line skirt"
61
+ },
62
+ "lower_garment": {
63
+ "type": "Not applicable - dress serves as complete outfit",
64
+ "color": "N/A",
65
+ "material": "N/A",
66
+ "features": "N/A"
67
+ },
68
+ "footwear": {
69
+ "type": "White leather sneakers",
70
+ "color": "Clean white with minimal accent details",
71
+ "material": "Leather upper with rubber sole",
72
+ "features": "Lace-up closure, low-profile design"
73
+ },
74
+ "outfit_summary": {
75
+ "aesthetic": "Casual chic",
76
+ "style_notes": "Floral pattern with modern styling",
77
+ "occasion_suitability": "Versatile for multiple occasions",
78
+ "color_harmony": "Cool-toned palette with neutral accents",
79
+ "overall_assessment": "This outfit demonstrates perfect balance between feminine charm and casual comfort..."
80
+ },
81
+ "confidence_score": 0.847,
82
+ "detected_items": [
83
+ {
84
+ "category": "dress",
85
+ "confidence": 0.892,
86
+ "bbox": [45.2, 78.1, 234.7, 456.3]
87
+ },
88
+ {
89
+ "category": "shoes",
90
+ "confidence": 0.756,
91
+ "bbox": [89.4, 423.8, 187.2, 478.9]
92
+ }
93
+ ]
94
+ },
95
+ "raw_analysis": "UPPER GARMENT:\nType: Floral midi dress\n...",
96
+ "processing_time": 2.347,
97
+ "model_info": {
98
+ "detection_model": "yainage90/fashion-object-detection",
99
+ "feature_model": "yainage90/fashion-image-feature-extractor",
100
+ "device": "cpu"
101
+ }
102
+ }
103
+ ```
104
+
105
+ ### 3. Object Detection Only
106
+
107
+ **POST** `/detect-objects`
108
+
109
+ Detect fashion objects in an image and return detection results.
110
+
111
+ **Request:**
112
+ - Method: `POST`
113
+ - Content-Type: `multipart/form-data`
114
+ - Body: Form data with `file` field containing the image
115
+
116
+ **Response:**
117
+ ```json
118
+ {
119
+ "detected_items": [
120
+ {
121
+ "category": "top",
122
+ "confidence": 0.892,
123
+ "bbox": [45.2, 78.1, 234.7, 298.5]
124
+ },
125
+ {
126
+ "category": "bottom",
127
+ "confidence": 0.756,
128
+ "bbox": [52.1, 285.3, 227.8, 423.9]
129
+ },
130
+ {
131
+ "category": "shoes",
132
+ "confidence": 0.634,
133
+ "bbox": [89.4, 423.8, 187.2, 478.9]
134
+ }
135
+ ]
136
+ }
137
+ ```
138
+
139
+ ### 4. Feature Extraction Only
140
+
141
+ **POST** `/extract-features`
142
+
143
+ Extract fashion features from an image.
144
+
145
+ **Request:**
146
+ - Method: `POST`
147
+ - Content-Type: `multipart/form-data`
148
+ - Body: Form data with `file` field containing the image
149
+
150
+ **Response:**
151
+ ```json
152
+ {
153
+ "feature_vector": [0.123, -0.456, 0.789, ...],
154
+ "feature_dimension": 128,
155
+ "processing_time": 1.234,
156
+ "model_used": "yainage90/fashion-image-feature-extractor"
157
+ }
158
+ ```
159
+
160
+ ### 5. Legacy Text Analysis
161
+
162
+ **POST** `/analyze-image`
163
+
164
+ Legacy endpoint returning text-based analysis.
165
+
166
+ **Response:**
167
+ ```json
168
+ {
169
+ "analysis": "Detailed text-based fashion analysis..."
170
+ }
171
+ ```
172
+
173
+ **POST** `/analyze-structured`
174
+
175
+ Legacy endpoint returning structured text analysis.
176
+
177
+ **Response:**
178
+ ```json
179
+ {
180
+ "analysis": "UPPER GARMENT:\nType: ...\n\nLOWER GARMENT:\n..."
181
+ }
182
+ ```
183
+
184
+ ## Data Models
185
+
186
+ ### GarmentDetails
187
+ ```json
188
+ {
189
+ "type": "string", // Garment type (e.g., "Floral midi dress")
190
+ "color": "string", // Color description with analysis
191
+ "material": "string", // Material type or inference
192
+ "features": "string" // Detailed features description
193
+ }
194
+ ```
195
+
196
+ ### OutfitSummary
197
+ ```json
198
+ {
199
+ "aesthetic": "string", // Overall aesthetic style
200
+ "style_notes": "string", // Pattern and design notes
201
+ "occasion_suitability": "string", // Suitable occasions
202
+ "color_harmony": "string", // Color analysis
203
+ "overall_assessment": "string" // Comprehensive summary
204
+ }
205
+ ```
206
+
207
+ ### StructuredAnalysisResponse
208
+ ```json
209
+ {
210
+ "upper_garment": "GarmentDetails",
211
+ "lower_garment": "GarmentDetails",
212
+ "footwear": "GarmentDetails",
213
+ "outfit_summary": "OutfitSummary",
214
+ "confidence_score": "float", // 0.0 to 1.0
215
+ "detected_items": "array" // Array of detection results
216
+ }
217
+ ```
218
+
219
+ ### DetectedItem
220
+ ```json
221
+ {
222
+ "category": "string", // Fashion category (top, bottom, shoes, etc.)
223
+ "confidence": "float", // Detection confidence (0.0 to 1.0)
224
+ "bbox": "array" // Bounding box [x1, y1, x2, y2]
225
+ }
226
+ ```
227
+
228
+ ## Fashion Categories
229
+
230
+ The system recognizes these fashion categories:
231
+ - `top` - Shirts, blouses, t-shirts
232
+ - `bottom` - Pants, jeans, skirts
233
+ - `dress` - Dresses of all types
234
+ - `outer` - Jackets, blazers, coats
235
+ - `shoes` - All types of footwear
236
+ - `bag` - Bags and purses
237
+ - `hat` - Hats and headwear
238
+
239
+ ## Error Responses
240
+
241
+ All endpoints return error responses in this format:
242
+
243
+ ```json
244
+ {
245
+ "detail": "Error message describing what went wrong"
246
+ }
247
+ ```
248
+
249
+ Common HTTP status codes:
250
+ - `400` - Bad Request (invalid input)
251
+ - `422` - Unprocessable Entity (validation error)
252
+ - `500` - Internal Server Error (processing failed)
253
+
254
+ ## Usage Examples
255
+
256
+ ### cURL Examples
257
+
258
+ ```bash
259
+ # Health check
260
+ curl -X GET "http://localhost:7861/health"
261
+
262
+ # Analyze image with JSON response
263
+ curl -X POST "http://localhost:7861/analyze-json" \
264
+ -F "file=@your_image.jpg"
265
+
266
+ # Detect objects only
267
+ curl -X POST "http://localhost:7861/detect-objects" \
268
+ -F "file=@your_image.jpg"
269
+
270
+ # Extract features only
271
+ curl -X POST "http://localhost:7861/extract-features" \
272
+ -F "file=@your_image.jpg"
273
+ ```
274
+
275
+ ### Python Examples
276
+
277
+ ```python
278
+ import requests
279
+
280
+ # Analyze image with structured JSON
281
+ with open('fashion_image.jpg', 'rb') as f:
282
+ response = requests.post(
283
+ 'http://localhost:7861/analyze-json',
284
+ files={'file': f}
285
+ )
286
+ result = response.json()
287
+
288
+ # Access structured data
289
+ upper_garment = result['structured_analysis']['upper_garment']
290
+ confidence = result['structured_analysis']['confidence_score']
291
+ processing_time = result['processing_time']
292
+
293
+ # Object detection only
294
+ with open('fashion_image.jpg', 'rb') as f:
295
+ response = requests.post(
296
+ 'http://localhost:7861/detect-objects',
297
+ files={'file': f}
298
+ )
299
+ detections = response.json()['detected_items']
300
+
301
+ for item in detections:
302
+ print(f"Found {item['category']} with {item['confidence']:.3f} confidence")
303
+ ```
304
+
305
+ ### JavaScript Examples
306
+
307
+ ```javascript
308
+ // Analyze image with fetch API
309
+ const formData = new FormData();
310
+ formData.append('file', fileInput.files[0]);
311
+
312
+ fetch('/analyze-json', {
313
+ method: 'POST',
314
+ body: formData
315
+ })
316
+ .then(response => response.json())
317
+ .then(data => {
318
+ console.log('Analysis result:', data.structured_analysis);
319
+ console.log('Processing time:', data.processing_time);
320
+ });
321
+
322
+ // Object detection
323
+ fetch('/detect-objects', {
324
+ method: 'POST',
325
+ body: formData
326
+ })
327
+ .then(response => response.json())
328
+ .then(data => {
329
+ data.detected_items.forEach(item => {
330
+ console.log(`${item.category}: ${item.confidence}`);
331
+ });
332
+ });
333
+ ```
334
+
335
+ ## Performance Notes
336
+
337
+ - **Processing Time**: Typical analysis takes 1-5 seconds depending on image size and hardware
338
+ - **Image Formats**: Supports JPEG, PNG, WebP, and other common formats
339
+ - **Image Size**: Optimal size is 224x224 to 512x512 pixels
340
+ - **Batch Processing**: Currently single image per request
341
+ - **Rate Limiting**: No rate limiting implemented in current version
342
+
343
+ ## Integration Tips
344
+
345
+ 1. **Error Handling**: Always check HTTP status codes and handle errors gracefully
346
+ 2. **Image Preprocessing**: Resize large images before upload for better performance
347
+ 3. **Confidence Thresholds**: Filter detection results by confidence score (>0.5 recommended)
348
+ 4. **Caching**: Consider caching results for identical images
349
+ 5. **Async Processing**: Use async/await patterns for better user experience
350
+
351
+ ## DeepFashion2 Integration
352
+
353
+ When the DeepFashion2 dataset is available, additional endpoints become active:
354
+
355
+ - `/deepfashion2/status` - Check dataset availability
356
+ - `/deepfashion2/statistics` - Get dataset statistics
357
+ - `/deepfashion2/evaluate` - Run model evaluation
358
+ - `/deepfashion2/train` - Start model training
359
+
360
+ See [DEEPFASHION2_INTEGRATION.md](DEEPFASHION2_INTEGRATION.md) for details.
361
+
362
+ ## Support
363
+
364
+ For issues or questions:
365
+ 1. Check the server logs for detailed error messages
366
+ 2. Verify image format and size requirements
367
+ 3. Test with the `/health` endpoint to ensure models are loaded
368
+ 4. Review this documentation for correct API usage
fast.py CHANGED
@@ -1,7 +1,7 @@
1
  from fastapi import FastAPI, HTTPException, UploadFile, File
2
  from fastapi.responses import JSONResponse, HTMLResponse, PlainTextResponse
3
  from pydantic import BaseModel
4
- from typing import List, Optional
5
  import json
6
  from PIL import Image
7
  import io
@@ -465,6 +465,114 @@ class HuggingFaceFashionAnalyzer:
465
 
466
  return " ".join(summary_sentences)
467
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
468
  def detect_fashion_objects(self, image):
469
  """Detect fashion objects using yainage90 fashion detection model"""
470
  if self.detection_model is None or self.detection_processor is None:
@@ -1612,9 +1720,36 @@ if DEEPFASHION2_AVAILABLE:
1612
  DEEPFASHION2_AVAILABLE = False
1613
 
1614
  # Request/Response models
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1615
  class AnalysisResponse(BaseModel):
1616
  analysis: str
1617
 
 
 
 
 
 
 
1618
  # API Endpoints
1619
  @app.get("/", response_class=HTMLResponse)
1620
  async def root():
@@ -1639,6 +1774,7 @@ async def root():
1639
  <br>
1640
  <button onclick="analyzeImage()" style="padding: 10px 20px; margin: 10px;">Analyze Fashion (Detailed)</button>
1641
  <button onclick="analyzeStructured()" style="padding: 10px 20px; margin: 10px;">Analyze Fashion (Structured)</button>
 
1642
  <button onclick="checkDeepFashion2Status()" style="padding: 10px 20px; margin: 10px; background-color: #6f42c1; color: white;">DeepFashion2 Status</button>
1643
  <br>
1644
  <a href="/refined-prompt" target="_blank" style="color: #007bff; text-decoration: none;">View Refined Prompt Format</a>
@@ -1706,6 +1842,45 @@ async def root():
1706
  }
1707
  }
1708
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1709
  async function checkDeepFashion2Status() {
1710
  document.getElementById('analysisText').textContent = 'Checking DeepFashion2 status...';
1711
  document.getElementById('result').style.display = 'block';
@@ -1811,6 +1986,82 @@ async def analyze_structured(file: UploadFile = File(...)):
1811
  except Exception as e:
1812
  raise HTTPException(status_code=500, detail=f"Error analyzing image: {str(e)}")
1813
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1814
  @app.get("/refined-prompt", response_class=PlainTextResponse)
1815
  async def get_refined_prompt():
1816
  """Get the refined prompt for clothing analysis"""
 
1
  from fastapi import FastAPI, HTTPException, UploadFile, File
2
  from fastapi.responses import JSONResponse, HTMLResponse, PlainTextResponse
3
  from pydantic import BaseModel
4
+ from typing import List, Optional, Dict, Any
5
  import json
6
  from PIL import Image
7
  import io
 
465
 
466
  return " ".join(summary_sentences)
467
 
468
+ def parse_structured_analysis(self, detection_results, basic_description):
469
+ """Parse detection results and description into structured JSON format"""
470
+
471
+ # Process detection results
472
+ detected_items = detection_results.get('detected_items', [])
473
+
474
+ # Categorize detected items
475
+ upper_items = []
476
+ lower_items = []
477
+ footwear_items = []
478
+
479
+ for item in detected_items:
480
+ category = item['category'].lower()
481
+ if category in ['top', 'shirt', 'blouse', 'outer', 'jacket', 'blazer', 'dress']:
482
+ upper_items.append(item)
483
+ elif category in ['bottom', 'pants', 'jeans', 'skirt']:
484
+ lower_items.append(item)
485
+ elif category in ['shoes']:
486
+ footwear_items.append(item)
487
+
488
+ # Extract upper garment details
489
+ if upper_items or 'dress' in basic_description.lower():
490
+ if upper_items:
491
+ garment_type = upper_items[0]['category'].title()
492
+ else:
493
+ garment_type = self.extract_garment_type(basic_description)
494
+
495
+ upper_garment = {
496
+ "type": garment_type,
497
+ "color": self.extract_colors(basic_description),
498
+ "material": self.extract_material(basic_description),
499
+ "features": self.extract_comprehensive_features(basic_description, garment_type)
500
+ }
501
+ else:
502
+ upper_garment = {
503
+ "type": "Not clearly visible",
504
+ "color": "Unable to determine",
505
+ "material": "Unable to determine",
506
+ "features": "Unable to determine"
507
+ }
508
+
509
+ # Extract lower garment details
510
+ if 'dress' in basic_description.lower() and not lower_items:
511
+ lower_garment = {
512
+ "type": "Not applicable - dress serves as complete outfit",
513
+ "color": "N/A",
514
+ "material": "N/A",
515
+ "features": "N/A"
516
+ }
517
+ elif lower_items:
518
+ garment_type = lower_items[0]['category'].title()
519
+ lower_garment = {
520
+ "type": garment_type,
521
+ "color": self.extract_colors(basic_description),
522
+ "material": self.extract_material(basic_description),
523
+ "features": self.extract_comprehensive_features(basic_description, garment_type)
524
+ }
525
+ else:
526
+ lower_garment = {
527
+ "type": "Not clearly visible",
528
+ "color": "Unable to determine",
529
+ "material": "Unable to determine",
530
+ "features": "Unable to determine"
531
+ }
532
+
533
+ # Extract footwear details
534
+ if footwear_items:
535
+ footwear_type = footwear_items[0]['category'].title()
536
+ footwear = {
537
+ "type": footwear_type,
538
+ "color": self.extract_colors(basic_description),
539
+ "material": self.extract_material(basic_description),
540
+ "features": self.extract_comprehensive_features(basic_description, footwear_type)
541
+ }
542
+ else:
543
+ footwear = {
544
+ "type": "Not clearly visible",
545
+ "color": "Unable to determine",
546
+ "material": "Unable to determine",
547
+ "features": "Unable to determine"
548
+ }
549
+
550
+ # Create outfit summary
551
+ outfit_summary_text = self.create_comprehensive_outfit_summary(detected_items, basic_description)
552
+
553
+ # Parse outfit summary into components
554
+ outfit_summary = {
555
+ "aesthetic": self.extract_style(basic_description),
556
+ "style_notes": self.extract_pattern(basic_description),
557
+ "occasion_suitability": "Versatile for multiple occasions",
558
+ "color_harmony": self.extract_colors(basic_description),
559
+ "overall_assessment": outfit_summary_text
560
+ }
561
+
562
+ # Calculate confidence score
563
+ confidence_scores = [item['confidence'] for item in detected_items if item['confidence'] > 0.3]
564
+ confidence_score = sum(confidence_scores) / len(confidence_scores) if confidence_scores else 0.5
565
+
566
+ # Create structured response
567
+ return StructuredAnalysisResponse(
568
+ upper_garment=GarmentDetails(**upper_garment),
569
+ lower_garment=GarmentDetails(**lower_garment),
570
+ footwear=GarmentDetails(**footwear),
571
+ outfit_summary=OutfitSummary(**outfit_summary),
572
+ confidence_score=round(confidence_score, 3),
573
+ detected_items=detected_items
574
+ )
575
+
576
  def detect_fashion_objects(self, image):
577
  """Detect fashion objects using yainage90 fashion detection model"""
578
  if self.detection_model is None or self.detection_processor is None:
 
1720
  DEEPFASHION2_AVAILABLE = False
1721
 
1722
  # Request/Response models
1723
+ class GarmentDetails(BaseModel):
1724
+ type: str
1725
+ color: str
1726
+ material: str
1727
+ features: str
1728
+
1729
+ class OutfitSummary(BaseModel):
1730
+ aesthetic: str
1731
+ style_notes: str
1732
+ occasion_suitability: str
1733
+ color_harmony: str
1734
+ overall_assessment: str
1735
+
1736
+ class StructuredAnalysisResponse(BaseModel):
1737
+ upper_garment: GarmentDetails
1738
+ lower_garment: GarmentDetails
1739
+ footwear: GarmentDetails
1740
+ outfit_summary: OutfitSummary
1741
+ confidence_score: float
1742
+ detected_items: List[Dict[str, Any]] = []
1743
+
1744
  class AnalysisResponse(BaseModel):
1745
  analysis: str
1746
 
1747
+ class DetailedAnalysisResponse(BaseModel):
1748
+ structured_analysis: StructuredAnalysisResponse
1749
+ raw_analysis: str
1750
+ processing_time: float
1751
+ model_info: Dict[str, str]
1752
+
1753
  # API Endpoints
1754
  @app.get("/", response_class=HTMLResponse)
1755
  async def root():
 
1774
  <br>
1775
  <button onclick="analyzeImage()" style="padding: 10px 20px; margin: 10px;">Analyze Fashion (Detailed)</button>
1776
  <button onclick="analyzeStructured()" style="padding: 10px 20px; margin: 10px;">Analyze Fashion (Structured)</button>
1777
+ <button onclick="analyzeJSON()" style="padding: 10px 20px; margin: 10px; background-color: #28a745; color: white;">Analyze Fashion (JSON)</button>
1778
  <button onclick="checkDeepFashion2Status()" style="padding: 10px 20px; margin: 10px; background-color: #6f42c1; color: white;">DeepFashion2 Status</button>
1779
  <br>
1780
  <a href="/refined-prompt" target="_blank" style="color: #007bff; text-decoration: none;">View Refined Prompt Format</a>
 
1842
  }
1843
  }
1844
 
1845
+ async function analyzeJSON() {
1846
+ const input = document.getElementById('imageInput');
1847
+ const file = input.files[0];
1848
+
1849
+ if (!file) {
1850
+ alert('Please select an image file');
1851
+ return;
1852
+ }
1853
+
1854
+ const formData = new FormData();
1855
+ formData.append('file', file);
1856
+
1857
+ document.getElementById('analysisText').textContent = 'Analyzing with JSON format... Please wait...';
1858
+ document.getElementById('result').style.display = 'block';
1859
+
1860
+ try {
1861
+ const response = await fetch('/analyze-json', {
1862
+ method: 'POST',
1863
+ body: formData
1864
+ });
1865
+
1866
+ const result = await response.json();
1867
+
1868
+ // Format JSON output nicely
1869
+ let jsonOutput = 'JSON FASHION ANALYSIS RESULT:\\n\\n';
1870
+ jsonOutput += 'STRUCTURED ANALYSIS:\\n';
1871
+ jsonOutput += JSON.stringify(result.structured_analysis, null, 2);
1872
+ jsonOutput += '\\n\\nPROCESSING INFO:\\n';
1873
+ jsonOutput += `Processing Time: ${result.processing_time.toFixed(3)} seconds\\n`;
1874
+ jsonOutput += `Device: ${result.model_info.device}\\n`;
1875
+ jsonOutput += `Detection Model: ${result.model_info.detection_model}\\n`;
1876
+ jsonOutput += `Feature Model: ${result.model_info.feature_model}\\n`;
1877
+
1878
+ document.getElementById('analysisText').textContent = jsonOutput;
1879
+ } catch (error) {
1880
+ document.getElementById('analysisText').textContent = 'Error: ' + error.message;
1881
+ }
1882
+ }
1883
+
1884
  async function checkDeepFashion2Status() {
1885
  document.getElementById('analysisText').textContent = 'Checking DeepFashion2 status...';
1886
  document.getElementById('result').style.display = 'block';
 
1986
  except Exception as e:
1987
  raise HTTPException(status_code=500, detail=f"Error analyzing image: {str(e)}")
1988
 
1989
+ @app.post("/analyze-json", response_model=DetailedAnalysisResponse)
1990
+ async def analyze_json(file: UploadFile = File(...)):
1991
+ """Analyze uploaded image and return structured JSON response"""
1992
+ try:
1993
+ start_time = time.time()
1994
+
1995
+ # Read image bytes
1996
+ image_bytes = await file.read()
1997
+
1998
+ # Process image
1999
+ image = analyzer.process_image_from_bytes(image_bytes)
2000
+
2001
+ # Get fashion object detection results
2002
+ detection_results = analyzer.detect_fashion_objects(image)
2003
+
2004
+ # Get basic image description
2005
+ basic_description = analyzer.get_basic_description(image)
2006
+
2007
+ # Extract structured information
2008
+ structured_analysis = analyzer.parse_structured_analysis(detection_results, basic_description)
2009
+
2010
+ # Get raw analysis for comparison
2011
+ raw_analysis = analyzer.analyze_clothing_structured_format(image_bytes)
2012
+
2013
+ processing_time = time.time() - start_time
2014
+
2015
+ return DetailedAnalysisResponse(
2016
+ structured_analysis=structured_analysis,
2017
+ raw_analysis=raw_analysis,
2018
+ processing_time=processing_time,
2019
+ model_info={
2020
+ "detection_model": analyzer.detection_ckpt if analyzer.detection_model else "Not available",
2021
+ "feature_model": analyzer.encoder_ckpt if analyzer.feature_encoder else "Not available",
2022
+ "device": analyzer.device
2023
+ }
2024
+ )
2025
+
2026
+ except Exception as e:
2027
+ raise HTTPException(status_code=500, detail=f"Error analyzing image: {str(e)}")
2028
+
2029
+ @app.post("/detect-objects", response_model=Dict[str, Any])
2030
+ async def detect_objects(file: UploadFile = File(...)):
2031
+ """Detect fashion objects and return JSON structure"""
2032
+ try:
2033
+ # Read image bytes
2034
+ image_bytes = await file.read()
2035
+
2036
+ # Process image
2037
+ image = analyzer.process_image_from_bytes(image_bytes)
2038
+
2039
+ # Get fashion object detection results
2040
+ detection_results = analyzer.detect_fashion_objects(image)
2041
+
2042
+ return detection_results
2043
+
2044
+ except Exception as e:
2045
+ raise HTTPException(status_code=500, detail=f"Error detecting objects: {str(e)}")
2046
+
2047
+ @app.post("/extract-features", response_model=Dict[str, Any])
2048
+ async def extract_features(file: UploadFile = File(...)):
2049
+ """Extract fashion features and return JSON structure"""
2050
+ try:
2051
+ # Read image bytes
2052
+ image_bytes = await file.read()
2053
+
2054
+ # Process image
2055
+ image = analyzer.process_image_from_bytes(image_bytes)
2056
+
2057
+ # Extract fashion features
2058
+ feature_results = analyzer.extract_fashion_features(image)
2059
+
2060
+ return feature_results
2061
+
2062
+ except Exception as e:
2063
+ raise HTTPException(status_code=500, detail=f"Error extracting features: {str(e)}")
2064
+
2065
  @app.get("/refined-prompt", response_class=PlainTextResponse)
2066
  async def get_refined_prompt():
2067
  """Get the refined prompt for clothing analysis"""