Initial commit

This commit is contained in:
Ayomide
2025-07-23 23:23:35 +01:00
commit d90c4c53ee
12 changed files with 35862 additions and 0 deletions
+122
View File
@@ -0,0 +1,122 @@
# Python
__pycache__/
*.py[cod]
*$py.class
*.so
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST
# Virtual Environment
venv/
env/
ENV/
.venv/
.env/
# Environment Variables
.env
.env.local
.env.development.local
.env.test.local
.env.production.local
# IDE and Editor Files
.vscode/
.idea/
*.swp
*.swo
*~
.DS_Store
Thumbs.db
# Logs
*.log
logs/
backend/*.log
# Machine Learning Models and Cache
*.pkl
*.pickle
data/image_embeddings*.pkl
data/embeddings/
models/
.cache/
# Temporary Files
*.tmp
*.temp
temp/
tmp/
# Flask
instance/
.webassets-cache
# Jupyter Notebooks
.ipynb_checkpoints
# PyTorch
*.pth
*.pt
# Transformers Cache
.transformers_cache/
# Large Data Files (uncomment if you don't want to track data files)
# data/*.csv
# data/*.json
# data/images/
# API Keys and Secrets
secrets.json
config/secrets.py
*.key
*.pem
# Database
*.db
*.sqlite
*.sqlite3
# Coverage Reports
htmlcov/
.coverage
.coverage.*
coverage.xml
*.cover
.hypothesis/
.pytest_cache/
# Operating System
.DS_Store
.DS_Store?
._*
.Spotlight-V100
.Trashes
ehthumbs.db
Thumbs.db
# Backup Files
*.bak
*.backup
*~
# Test Files
test_output/
test_results/
+149
View File
@@ -0,0 +1,149 @@
from flask import Flask, request, jsonify
from tag_identification import TagIdentifier
from tag_match import TagMatcher
from image_similarity import ImageSimilarity
import os
import time
app = Flask(__name__)
# Initialize components
print("Initializing Tag Scan System...")
tag_identifier = TagIdentifier()
tag_matcher = TagMatcher('data/tag_guides_clean.json')
image_similarity = ImageSimilarity('data/expert_data.csv', 'data/community_data.csv')
print("System initialized successfully!")
@app.route('/')
def home():
return jsonify({
'message': 'DS Task Tag Scan System API',
'version': '1.0',
'endpoints': {
'/get_tag': 'POST - Analyze tag image and find similar tags',
'/status': 'GET - Health check'
}
})
@app.route('/get_tag', methods=['POST'])
def get_tag():
start_time = time.time()
try:
# Validate request
data = request.get_json()
if not data or 'image_url' not in data:
return jsonify({'error': 'Missing image_url in request'}), 400
image_url = data['image_url']
# Load and process image
print(f"Processing image: {image_url}")
image = tag_identifier.load_image(image_url)
# Identify brand and extract text
brand, extracted_text = tag_identifier.identify_brand(image)
print(f"Identified brand: {brand}, Extracted text: {extracted_text}")
# Find text-based matches using extracted text or brand
search_query = extracted_text if extracted_text else brand
text_matches = tag_matcher.find_matches(search_query)
# Find visually similar images
image_matches = image_similarity.find_similar(image_url)
# Format response
results = []
# Add text-based matches
for match in text_matches:
results.append({
"tag": match["name"],
"year_start": str(match["year_start"]) if match["year_start"] else "unknown",
"year_end": str(match["year_end"]) if match["year_end"] else "unknown",
"match_type": "text",
"confidence": match.get("confidence", 0.0)
})
# Add image similarity results
if image_matches:
similar_images_data = {
"similar_images": [img["image_url"] for img in image_matches],
"appraisal_value": [img["appraisal_value"] for img in image_matches],
"years": [img["year"] for img in image_matches],
"status": ["public" if img["status"] == 1 else "private" for img in image_matches],
"brands": [img["brand_name"] for img in image_matches],
"similarity_scores": [img["similarity_score"] for img in image_matches],
"match_type": "visual"
}
results.append(similar_images_data)
# Calculate processing time
processing_time = time.time() - start_time
response = {
"success": True,
"results": results,
"metadata": {
"identified_brand": brand,
"extracted_text": extracted_text,
"processing_time_seconds": round(processing_time, 2),
"total_matches": len(text_matches) + len(image_matches)
}
}
print(f"Request completed in {processing_time:.2f} seconds")
return jsonify(response)
except ValueError as ve:
# Handle image loading errors
return jsonify({
'success': False,
'error': f'Image processing error: {str(ve)}'
}), 400
except Exception as e:
# Handle other errors
print(f"Unexpected error: {e}")
return jsonify({
'success': False,
'error': f'Internal server error: {str(e)}'
}), 500
@app.route('/status', methods=['GET'])
def status():
"""Health check endpoint"""
try:
# Quick system check
system_status = {
'status': 'healthy',
'components': {
'tag_identifier': 'ready',
'tag_matcher': 'ready',
'image_similarity': 'ready'
},
'database_stats': {
'tag_guides': len(tag_matcher.data) if hasattr(tag_matcher, 'data') else 0,
'image_database': len(image_similarity.image_data) if hasattr(image_similarity, 'image_data') else 0
}
}
return jsonify(system_status)
except Exception as e:
return jsonify({
'status': 'unhealthy',
'error': str(e)
}), 503
@app.route('/favicon.ico')
def favicon():
return '', 404
if __name__ == '__main__':
print("Starting DS Task Tag Scan System...")
app.run(host='0.0.0.0', port=5000, debug=False)
+42
View File
@@ -0,0 +1,42 @@
import os
from dotenv import load_dotenv
# Load environment variables from .env file
load_dotenv()
class Config:
"""Configuration settings for DS Task Tag Scan System"""
# Flask Settings
DEBUG = os.getenv('DEBUG', 'False').lower() == 'true'
HOST = os.getenv('HOST', '0.0.0.0')
PORT = int(os.getenv('PORT', 5000))
# Data Paths
TAG_GUIDES_PATH = os.getenv('TAG_GUIDES_PATH', 'data/tag_guides_clean.json')
EXPERT_DATA_PATH = os.getenv('EXPERT_DATA_PATH', 'data/expert_data.csv')
COMMUNITY_DATA_PATH = os.getenv('COMMUNITY_DATA_PATH', 'data/community_data.csv')
# Model Settings
CLIP_MODEL = os.getenv('CLIP_MODEL', 'openai/clip-vit-base-patch16')
MAX_IMAGES = int(os.getenv('MAX_IMAGES', 200)) # Limit for testing
# Cache Settings
EMBEDDINGS_CACHE_FILE = os.getenv('EMBEDDINGS_CACHE_FILE', 'data/image_embeddings_200.pkl')
USE_CACHE = os.getenv('USE_CACHE', 'True').lower() == 'true'
# Processing Settings
REQUEST_TIMEOUT = int(os.getenv('REQUEST_TIMEOUT', 60)) # seconds
IMAGE_TIMEOUT = int(os.getenv('IMAGE_TIMEOUT', 10)) # seconds
MAX_SIMILARITY_RESULTS = int(os.getenv('MAX_SIMILARITY_RESULTS', 5))
# OCR Settings
OCR_METHOD = os.getenv('OCR_METHOD', 'auto') # 'auto', 'easyocr', 'clip_only'
# Optional: LLM Enhancement (Groq)
GROQ_API_KEY = os.getenv('GROQ_API_KEY', None)
USE_LLM_ENHANCEMENT = os.getenv('USE_LLM_ENHANCEMENT', 'False').lower() == 'true'
# Create config instance
config = Config()
+174
View File
@@ -0,0 +1,174 @@
import numpy as np
from sklearn.neighbors import NearestNeighbors
from sklearn.metrics.pairwise import cosine_similarity
from tag_identification import TagIdentifier
import pandas as pd
import pickle
import os
class ImageSimilarity:
def __init__(self, expert_data_path, community_data_path):
self.identifier = TagIdentifier()
# Load both datasets
self.expert_data = pd.read_csv(expert_data_path)
self.community_data = pd.read_csv(community_data_path)
# Combine and prepare data
self._prepare_image_data()
# Try to load precomputed embeddings, otherwise compute them
self.embeddings_file = 'data/image_embeddings_200.pkl'
if os.path.exists(self.embeddings_file):
self._load_embeddings()
else:
self._compute_and_save_embeddings()
# Build nearest neighbors index
self._build_index()
def _prepare_image_data(self):
"""Combine expert and community data and limit to 200 images"""
# Prepare expert data
expert_cols = ['brand_name', 'appraisal_value', 'front_tag', 'status']
if 'year' in self.expert_data.columns:
expert_cols.append('year')
expert_images = self.expert_data[expert_cols].copy()
expert_images = expert_images.rename(columns={'front_tag': 'image_url'})
expert_images['source'] = 'expert'
# Prepare community data
community_cols = ['brand_name', 'appraisal_value', 'front_tag', 'status']
if 'year' in self.community_data.columns:
community_cols.append('year')
community_images = self.community_data[community_cols].copy()
community_images = community_images.rename(columns={'front_tag': 'image_url'})
community_images['source'] = 'community'
# Combine datasets
self.image_data = pd.concat([expert_images, community_images], ignore_index=True)
self.image_data = self.image_data.dropna(subset=['image_url'])
# LIMIT TO 200 IMAGES FOR TESTING
print(f"Total images available: {len(self.image_data)}")
self.image_data = self.image_data.head(200)
print(f"Limited to first 200 images for testing")
# Reset index for consistent indexing
self.image_data = self.image_data.reset_index(drop=True)
def _compute_and_save_embeddings(self):
"""Compute CLIP embeddings for 200 images and save to file"""
print(f"Computing embeddings for {len(self.image_data)} images...")
embeddings = []
valid_indices = []
for idx, row in self.image_data.iterrows():
try:
image = self.identifier.load_image(row['image_url'])
features = self.identifier.get_image_features(image)
embeddings.append(features)
valid_indices.append(idx)
# Progress update every 25 images
if len(embeddings) % 25 == 0:
print(f"Processed {len(embeddings)}/200 images...")
except Exception as e:
print(f"Failed to process image {idx}: {e}")
continue
# Store embeddings and update data to only include valid images
self.embeddings = np.array(embeddings)
self.image_data = self.image_data.iloc[valid_indices].reset_index(drop=True)
# Save to file
with open(self.embeddings_file, 'wb') as f:
pickle.dump({
'embeddings': self.embeddings,
'image_data': self.image_data
}, f)
print(f"✅ Computed and saved embeddings for {len(embeddings)} images")
def _load_embeddings(self):
"""Load precomputed embeddings from file"""
print("Loading precomputed embeddings...")
with open(self.embeddings_file, 'rb') as f:
data = pickle.load(f)
self.embeddings = data['embeddings']
self.image_data = data['image_data']
print(f"✅ Loaded embeddings for {len(self.embeddings)} images")
def _build_index(self):
"""Build nearest neighbors index for fast similarity search"""
if len(self.embeddings) > 0:
self.nn_model = NearestNeighbors(
n_neighbors=min(10, len(self.embeddings)),
metric='cosine'
)
self.nn_model.fit(self.embeddings)
else:
self.nn_model = None
def find_similar(self, image_url, top_n=5):
"""Find visually similar images using CLIP embeddings"""
if self.nn_model is None or len(self.embeddings) == 0:
return []
try:
# Get features for query image
query_image = self.identifier.load_image(image_url)
query_features = self.identifier.get_image_features(query_image)
# Find similar images
distances, indices = self.nn_model.kneighbors(
[query_features],
n_neighbors=min(top_n, len(self.embeddings))
)
results = []
for i, idx in enumerate(indices[0]):
row = self.image_data.iloc[idx]
result = {
'image_url': row['image_url'],
'brand_name': row.get('brand_name', 'unknown'),
'appraisal_value': float(row.get('appraisal_value', 0)),
'status': int(row.get('status', 1)),
'source': row.get('source', 'unknown'),
'similarity_score': float(1 - distances[0][i]), # Convert distance to similarity
'year': self._extract_year_from_metadata(row)
}
results.append(result)
return results
except Exception as e:
print(f"Error in similarity search: {e}")
return []
def _extract_year_from_metadata(self, item):
"""Extract year information from various possible fields"""
# Try different year fields
for year_field in ['year', 'from_decade', 'to_decade', 'manufacturing_year']:
if year_field in item and pd.notna(item[year_field]):
year_val = item[year_field]
if isinstance(year_val, (int, float)) and year_val > 1900:
return str(int(year_val))
elif isinstance(year_val, str) and year_val.isdigit():
return year_val
# Try to extract from brand_name or other text fields
if 'brand_name' in item and pd.notna(item['brand_name']):
text = str(item['brand_name'])
# Look for 4-digit years in text
import re
years = re.findall(r'\b(19|20)\d{2}\b', text)
if years:
return years[0]
return "unknown"
Binary file not shown.
+88
View File
@@ -0,0 +1,88 @@
from transformers import CLIPProcessor, CLIPModel
from PIL import Image
import requests
import torch
import easyocr
import numpy as np
class TagIdentifier:
def __init__(self):
self.model = CLIPModel.from_pretrained("openai/clip-vit-base-patch16")
self.processor = CLIPProcessor.from_pretrained("openai/clip-vit-base-patch16")
# Initialize OCR reader
self.ocr_reader = easyocr.Reader(['en'])
# Brand keywords for identification
self.brand_keywords = [
'nike', 'adidas', 'puma', 'reebok', 'champion', 'hanes',
'fruit of the loom', 'gildan', 'jerzees', 'russell',
'american apparel', 'next level', 'bella canvas'
]
def load_image(self, image_url):
try:
response = requests.get(image_url, stream=True, timeout=10)
response.raise_for_status()
image = Image.open(response.raw)
return image
except Exception as e:
raise ValueError(f"Failed to load image: {str(e)}")
def get_image_features(self, image):
"""Get CLIP embeddings for the image"""
inputs = self.processor(images=image, return_tensors="pt")
with torch.no_grad():
features = self.model.get_image_features(**inputs)
return features.cpu().numpy().flatten()
def extract_text_from_image(self, image):
"""Extract text from tag image using OCR"""
try:
# Convert PIL image to numpy array
image_np = np.array(image)
# Use EasyOCR to extract text
results = self.ocr_reader.readtext(image_np)
# Combine all detected text
extracted_text = " ".join([result[1] for result in results])
return extracted_text.lower()
except Exception as e:
print(f"OCR extraction failed: {e}")
return ""
def identify_brand(self, image):
"""Try to identify brand from image using both OCR and CLIP"""
# OCR-based brand detection
extracted_text = self.extract_text_from_image(image)
for brand in self.brand_keywords:
if brand in extracted_text:
return brand, extracted_text
# CLIP-based brand classification (if OCR fails)
# Create text prompts for each brand
brand_prompts = [f"a {brand} clothing tag" for brand in self.brand_keywords]
brand_prompts.append("a generic clothing tag")
# Get image and text features
inputs = self.processor(
text=brand_prompts,
images=image,
return_tensors="pt",
padding=True
)
with torch.no_grad():
outputs = self.model(**inputs)
probs = outputs.logits_per_image.softmax(dim=1)
# Get best match
best_idx = probs.argmax().item()
if best_idx < len(self.brand_keywords):
return self.brand_keywords[best_idx], extracted_text
return "unknown", extracted_text
+43
View File
@@ -0,0 +1,43 @@
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.metrics.pairwise import cosine_similarity
import pandas as pd
import numpy as np
import json
class TagMatcher:
def __init__(self, tag_data_path):
# Load and process JSON data
with open(tag_data_path, 'r') as f:
data = json.load(f)
# Convert to DataFrame and flatten structure
self.data = pd.json_normalize(data['tag_guides'])
# Prepare text data for matching
self.text_data = self.data['name'].tolist()
self.vectorizer = TfidfVectorizer()
self._fit_vectorizer()
def _fit_vectorizer(self):
self.vectorizer.fit(self.text_data)
def find_matches(self, query_text, top_n=5):
query_vec = self.vectorizer.transform([query_text])
tag_vecs = self.vectorizer.transform(self.text_data)
similarities = cosine_similarity(query_vec, tag_vecs)
top_indices = np.argsort(similarities[0])[-top_n:][::-1]
# Return matches with relevant fields
results = []
for idx in top_indices:
match = self.data.iloc[idx]
results.append({
'name': match['name'],
'year_start': match['year_start'],
'year_end': match['year_end'],
'images': match['images']
})
return results
File diff suppressed because it is too large Load Diff
+2277
View File
File diff suppressed because it is too large Load Diff
+854
View File
@@ -0,0 +1,854 @@
{
"success": true,
"tag_guides": [
{
"id": 1,
"name": "Alstyle Apparel & Activewear T-Shirt Tags",
"year_start": "1995",
"year_end": "2006",
"category": null,
"brand_id": null,
"status": 1,
"created_at": "2024-12-09T16:55:26.000Z",
"updated_at": "2024-12-09T16:55:26.000Z",
"images_and_years": "https://s3.amazonaws.com/com.images.legiteem8/alstyle/alstyle-1.jpg==1995;;https://s3.amazonaws.com/com.images.legiteem8/alstyle/alstyle-2.jpg==1997;;https://s3.amazonaws.com/com.images.legiteem8/alstyle/alstyle-3.jpg==1998;;https://s3.amazonaws.com/com.images.legiteem8/alstyle/alstyle-4.jpg==1999;;https://s3.amazonaws.com/com.images.legiteem8/alstyle/alstyle-5.jpg==2000;;https://s3.amazonaws.com/com.images.legiteem8/alstyle/alstyle-6.jpg==2002;;https://s3.amazonaws.com/com.images.legiteem8/alstyle/alstyle-7.jpg==2006;;https://s3.amazonaws.com/com.images.legiteem8/alstyle/alstyle-8.jpg==-",
"images": [
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/alstyle/alstyle-1.jpg",
"year": "1995"
},
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/alstyle/alstyle-2.jpg",
"year": "1997"
},
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/alstyle/alstyle-3.jpg",
"year": "1998"
},
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/alstyle/alstyle-4.jpg",
"year": "1999"
},
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/alstyle/alstyle-5.jpg",
"year": "2000"
},
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/alstyle/alstyle-6.jpg",
"year": "2002"
},
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/alstyle/alstyle-7.jpg",
"year": "2006"
},
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/alstyle/alstyle-8.jpg",
"year": "-"
}
]
},
{
"id": 2,
"name": "Anvil T-Shirt Tags",
"year_start": "1989",
"year_end": "2007",
"category": null,
"brand_id": 69,
"status": 1,
"created_at": "2024-12-09T13:13:02.000Z",
"updated_at": "2024-12-09T13:13:02.000Z",
"images_and_years": "https://s3.amazonaws.com/com.images.legiteem8/anvil/anvil-1.jpg==1989-1993;;https://s3.amazonaws.com/com.images.legiteem8/anvil/anvil-2.jpg==1991-1997;;https://s3.amazonaws.com/com.images.legiteem8/anvil/anvil-3.jpg==1992-1999;;https://s3.amazonaws.com/com.images.legiteem8/anvil/anvil-4.jpg==1993-1994;;https://s3.amazonaws.com/com.images.legiteem8/anvil/anvil-5.jpg==1994-1996;;https://s3.amazonaws.com/com.images.legiteem8/anvil/anvil-6.jpg==1994-1997;;https://s3.amazonaws.com/com.images.legiteem8/anvil/anvil-7.jpg==1995-1999;;https://s3.amazonaws.com/com.images.legiteem8/anvil/anvil-8.jpg==1996-2004;;https://s3.amazonaws.com/com.images.legiteem8/anvil/anvil-9.jpg==1994;;https://s3.amazonaws.com/com.images.legiteem8/anvil/anvil-10.jpg==1996;;https://s3.amazonaws.com/com.images.legiteem8/anvil/anvil-11.jpg==1998",
"images": [
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/anvil/anvil-1.jpg",
"year": "1989-1993"
},
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/anvil/anvil-2.jpg",
"year": "1991-1997"
},
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/anvil/anvil-3.jpg",
"year": "1992-1999"
},
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/anvil/anvil-4.jpg",
"year": "1993-1994"
},
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/anvil/anvil-5.jpg",
"year": "1994-1996"
},
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/anvil/anvil-6.jpg",
"year": "1994-1997"
},
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/anvil/anvil-7.jpg",
"year": "1995-1999"
},
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/anvil/anvil-8.jpg",
"year": "1996-1998"
},
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/anvil/anvil-9.jpg",
"year": "1994"
},
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/anvil/anvil-10.jpg",
"year": "1996"
},
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/anvil/anvil-11.jpg",
"year": "1998"
}
]
},
{
"id": 3,
"name": "Ched and Anvil T-Shirt Tags",
"year_start": "1976",
"year_end": "1988",
"category": null,
"brand_id": 212,
"status": 1,
"created_at": "2024-12-10T13:21:49.000Z",
"updated_at": "2024-12-10T13:21:49.000Z",
"images_and_years": "https://s3.amazonaws.com/com.images.legiteem8/ched/ched-1.jpg==1976-1977;;https://s3.amazonaws.com/com.images.legiteem8/ched/ched-2.jpg==1976-1979;;https://s3.amazonaws.com/com.images.legiteem8/ched/ched-3.jpg==1979-1988;;https://s3.amazonaws.com/com.images.legiteem8/ched/ched-4.jpg==1984-1988;;https://s3.amazonaws.com/com.images.legiteem8/ched/ched-5.jpg==1976-1985;;https://s3.amazonaws.com/com.images.legiteem8/ched/ched-6.jpg==1979-1983;;https://s3.amazonaws.com/com.images.legiteem8/ched/ched-7.jpg==1985-1989;;https://s3.amazonaws.com/com.images.legiteem8/ched/ched-8.jpg==1986-1990;;https://s3.amazonaws.com/com.images.legiteem8/ched/ched-9.jpg==1988-1990",
"images": [
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/ched/ched-1.jpg",
"year": "1976-1977"
},
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/ched/ched-2.jpg",
"year": "1976-1979"
},
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/ched/ched-3.jpg",
"year": "1979-1988"
},
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/ched/ched-4.jpg",
"year": "1976-1985"
},
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/ched/ched-5.jpg",
"year": "1979-1983"
},
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/ched/ched-6.jpg",
"year": "1984-1988"
},
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/ched/ched-7.jpg",
"year": "1985-1989"
},
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/ched/ched-8.jpg",
"year": "1986-1990"
},
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/ched/ched-9.jpg",
"year": "1988-1990"
}
]
},
{
"id": 4,
"name": "Delta T-Shirt Tags",
"year_start": "1988",
"year_end": "2014",
"category": null,
"brand_id": null,
"status": 1,
"created_at": "2024-12-10T13:22:19.000Z",
"updated_at": "2024-12-10T13:22:19.000Z",
"images_and_years": "https://s3.amazonaws.com/com.images.legiteem8/delta/delta-1.jpg==1988;;https://s3.amazonaws.com/com.images.legiteem8/delta/delta-2.jpg==1988;;https://s3.amazonaws.com/com.images.legiteem8/delta/delta-3.jpg==1991;;https://s3.amazonaws.com/com.images.legiteem8/delta/delta-4.jpg==1993;;https://s3.amazonaws.com/com.images.legiteem8/delta/delta-5.jpg==1996;;https://s3.amazonaws.com/com.images.legiteem8/delta/delta-6.jpg==1996;;https://s3.amazonaws.com/com.images.legiteem8/delta/delta-7.jpg==2001;;https://s3.amazonaws.com/com.images.legiteem8/delta/delta-8.jpg==2002;;https://s3.amazonaws.com/com.images.legiteem8/delta/delta-9.jpg==2002;;https://s3.amazonaws.com/com.images.legiteem8/delta/delta-10.jpg==2004;;https://s3.amazonaws.com/com.images.legiteem8/delta/delta-11.jpg==2004;;https://s3.amazonaws.com/com.images.legiteem8/delta/delta-12.jpg==2009;;https://s3.amazonaws.com/com.images.legiteem8/delta/delta-13.jpg==2009;;https://s3.amazonaws.com/com.images.legiteem8/delta/delta-14.jpg==2013;;https://s3.amazonaws.com/com.images.legiteem8/delta/delta-15.jpg==2013",
"images": [
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/delta/delta-1.jpg",
"year": "1988"
},
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/delta/delta-2.jpg",
"year": "1988"
},
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/delta/delta-3.jpg",
"year": "1991"
},
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/delta/delta-4.jpg",
"year": "1993"
},
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/delta/delta-5.jpg",
"year": "1996"
},
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/delta/delta-6.jpg",
"year": "1996"
},
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/delta/delta-7.jpg",
"year": "2001"
},
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/delta/delta-8.jpg",
"year": "2002"
},
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/delta/delta-9.jpg",
"year": "2004"
},
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/delta/delta-10.jpg",
"year": "2002"
},
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/delta/delta-11.jpg",
"year": "2002"
},
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/delta/delta-12.jpg",
"year": "2004"
},
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/delta/delta-13.jpg",
"year": "2004"
},
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/delta/delta-14.jpg",
"year": "-"
},
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/delta/delta-15.jpg",
"year": "2009"
}
]
},
{
"id": 5,
"name": "Fruit of the Loom ",
"year_start": "1970",
"year_end": "1998",
"category": null,
"brand_id": 396,
"status": 1,
"created_at": "2024-12-10T13:22:52.000Z",
"updated_at": "2024-12-10T13:22:52.000Z",
"images_and_years": null,
"images": []
},
{
"id": 6,
"name": "Giant T-Shirt Tags",
"year_start": "1991",
"year_end": "1996",
"category": null,
"brand_id": 425,
"status": 1,
"created_at": "2024-12-10T13:23:37.000Z",
"updated_at": "2024-12-10T13:23:37.000Z",
"images_and_years": "https://s3.amazonaws.com/com.images.legiteem8/giant/giant-1.jpg==1991;;https://s3.amazonaws.com/com.images.legiteem8/giant/giant-2.jpg==1991;;https://s3.amazonaws.com/com.images.legiteem8/giant/giant-3.jpg==1993;;https://s3.amazonaws.com/com.images.legiteem8/giant/giant-4.jpg==1994;;https://s3.amazonaws.com/com.images.legiteem8/giant/giant-5.jpg==1994;;https://s3.amazonaws.com/com.images.legiteem8/giant/giant-6.jpg==1996;;https://s3.amazonaws.com/com.images.legiteem8/giant/giant-7.jpg==1996",
"images": [
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/giant/giant-1.jpg",
"year": "1991"
},
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/giant/giant-2.jpg",
"year": "1991"
},
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/giant/giant-3.jpg",
"year": "1993"
},
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/giant/giant-4.jpg",
"year": "1994"
},
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/giant/giant-5.jpg",
"year": "1996"
},
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/giant/giant-6.jpg",
"year": "1994"
},
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/giant/giant-7.jpg",
"year": "1996"
}
]
},
{
"id": 7,
"name": "Gildan T-Shirt Tags",
"year_start": "1995",
"year_end": "2002",
"category": null,
"brand_id": 425,
"status": 1,
"created_at": "2024-12-10T13:24:04.000Z",
"updated_at": "2024-12-10T13:24:04.000Z",
"images_and_years": "https://s3.amazonaws.com/com.images.legiteem8/gildan/gildan-1.jpg==1995;;https://s3.amazonaws.com/com.images.legiteem8/gildan/gildan-2.jpg==1996;;https://s3.amazonaws.com/com.images.legiteem8/gildan/gildan-3.jpg==1997;;https://s3.amazonaws.com/com.images.legiteem8/gildan/gildan-4.jpg==1997;;https://s3.amazonaws.com/com.images.legiteem8/gildan/gildan-5.jpg==1998;;https://s3.amazonaws.com/com.images.legiteem8/gildan/gildan-6.jpg==1999;;https://s3.amazonaws.com/com.images.legiteem8/gildan/gildan-7.jpg==2000;;https://s3.amazonaws.com/com.images.legiteem8/gildan/gildan-8.jpg==2001;;https://s3.amazonaws.com/com.images.legiteem8/gildan/gildan-9.jpg==2002",
"images": [
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/gildan/gildan-1.jpg",
"year": "1995"
},
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/gildan/gildan-2.jpg",
"year": "1997"
},
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/gildan/gildan-3.jpg",
"year": "1996"
},
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/gildan/gildan-4.jpg",
"year": "1997"
},
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/gildan/gildan-5.jpg",
"year": "1998"
},
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/gildan/gildan-6.jpg",
"year": "1999"
},
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/gildan/gildan-7.jpg",
"year": "2000"
},
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/gildan/gildan-8.jpg",
"year": "2001"
},
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/gildan/gildan-9.jpg",
"year": "2002"
}
]
},
{
"id": 8,
"name": "Hanes T-Shirt Tags ",
"year_start": "1989",
"year_end": "1997",
"category": null,
"brand_id": 466,
"status": 1,
"created_at": "2024-12-10T13:24:34.000Z",
"updated_at": "2024-12-10T13:24:34.000Z",
"images_and_years": "https://s3.amazonaws.com/com.images.legiteem8/hanes/hanes-1.jpg==1989;;https://s3.amazonaws.com/com.images.legiteem8/hanes/hanes-2.jpg==1990;;https://s3.amazonaws.com/com.images.legiteem8/hanes/hanes-3.jpg==1991;;https://s3.amazonaws.com/com.images.legiteem8/hanes/hanes-4.jpg==1992;;https://s3.amazonaws.com/com.images.legiteem8/hanes/hanes-5.jpg==1993;;https://s3.amazonaws.com/com.images.legiteem8/hanes/hanes-6.jpg==1994;;https://s3.amazonaws.com/com.images.legiteem8/hanes/hanes-7.jpg==1995;;https://s3.amazonaws.com/com.images.legiteem8/hanes/hanes-8.jpg==1996;;https://s3.amazonaws.com/com.images.legiteem8/hanes/hanes-9.jpg==1997",
"images": [
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/hanes/hanes-1.jpg",
"year": "1989"
},
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/hanes/hanes-2.jpg",
"year": "1990"
},
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/hanes/hanes-3.jpg",
"year": "1991"
},
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/hanes/hanes-4.jpg",
"year": "1992"
},
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/hanes/hanes-5.jpg",
"year": "1993"
},
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/hanes/hanes-6.jpg",
"year": "1994"
},
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/hanes/hanes-7.jpg",
"year": "1995"
},
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/hanes/hanes-8.jpg",
"year": "1997"
},
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/hanes/hanes-9.jpg",
"year": "1996"
}
]
},
{
"id": 9,
"name": "Jerzees T-Shirt Tags",
"year_start": "1985",
"year_end": "1998",
"category": null,
"brand_id": null,
"status": 1,
"created_at": "2024-12-10T13:25:12.000Z",
"updated_at": "2024-12-10T13:25:12.000Z",
"images_and_years": "https://s3.amazonaws.com/com.images.legiteem8/jerzees/jerzees-1.jpg==1985;;https://s3.amazonaws.com/com.images.legiteem8/jerzees/jerzees-2.jpg==1985;;https://s3.amazonaws.com/com.images.legiteem8/jerzees/jerzees-3.jpg==1987;;https://s3.amazonaws.com/com.images.legiteem8/jerzees/jerzees-4.jpg==1991;;https://s3.amazonaws.com/com.images.legiteem8/jerzees/jerzees-5.jpg==1992;;https://s3.amazonaws.com/com.images.legiteem8/jerzees/jerzees-6.jpg==1995;;https://s3.amazonaws.com/com.images.legiteem8/jerzees/jerzees-7.jpg==1996;;https://s3.amazonaws.com/com.images.legiteem8/jerzees/jerzees-8.jpg==1997;;https://s3.amazonaws.com/com.images.legiteem8/jerzees/jerzees-9.jpg==1998",
"images": [
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/jerzees/jerzees-1.jpg",
"year": "1985"
},
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/jerzees/jerzees-2.jpg",
"year": "1985"
},
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/jerzees/jerzees-3.jpg",
"year": "1987"
},
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/jerzees/jerzees-4.jpg",
"year": "1991"
},
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/jerzees/jerzees-5.jpg",
"year": "1992"
},
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/jerzees/jerzees-6.jpg",
"year": "1995"
},
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/jerzees/jerzees-7.jpg",
"year": "1996"
},
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/jerzees/jerzees-8.jpg",
"year": "1997"
},
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/jerzees/jerzees-9.jpg",
"year": "1998"
}
]
},
{
"id": 10,
"name": "Oneita T-Shirt Tags",
"year_start": "1984",
"year_end": "1989",
"category": null,
"brand_id": null,
"status": 1,
"created_at": "2024-12-10T13:25:37.000Z",
"updated_at": "2024-12-10T13:25:37.000Z",
"images_and_years": "https://s3.amazonaws.com/com.images.legiteem8/oneita/oneita-1.jpg==1984;;https://s3.amazonaws.com/com.images.legiteem8/oneita/oneita-2.jpg==1985;;https://s3.amazonaws.com/com.images.legiteem8/oneita/oneita-3.jpg==1987;;https://s3.amazonaws.com/com.images.legiteem8/oneita/oneita-4.jpg==1988;;https://s3.amazonaws.com/com.images.legiteem8/oneita/oneita-5.jpg==1993;;https://s3.amazonaws.com/com.images.legiteem8/oneita/oneita-6.jpg==1996;;https://s3.amazonaws.com/com.images.legiteem8/oneita/oneita-7.jpg==1996;;https://s3.amazonaws.com/com.images.legiteem8/oneita/oneita-8.jpg==1999;;https://s3.amazonaws.com/com.images.legiteem8/oneita/oneita-9.jpg==1999",
"images": [
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/oneita/oneita-1.jpg",
"year": "1984"
},
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/oneita/oneita-2.jpg",
"year": "1985"
},
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/oneita/oneita-3.jpg",
"year": "1987"
},
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/oneita/oneita-4.jpg",
"year": "1988"
},
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/oneita/oneita-5.jpg",
"year": "1993"
},
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/oneita/oneita-6.jpg",
"year": "1996"
},
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/oneita/oneita-7.jpg",
"year": "1996"
},
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/oneita/oneita-8.jpg",
"year": "1999"
},
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/oneita/oneita-9.jpg",
"year": "1999"
}
]
},
{
"id": 11,
"name": "Screen Stars T-Shirt Tags",
"year_start": "1980",
"year_end": "1994",
"category": null,
"brand_id": null,
"status": 1,
"created_at": "2024-12-10T13:26:14.000Z",
"updated_at": "2024-12-10T13:26:14.000Z",
"images_and_years": "https://s3.amazonaws.com/com.images.legiteem8/stars/stars-1.jpg==1980;;https://s3.amazonaws.com/com.images.legiteem8/stars/stars-2.jpg==1980;;https://s3.amazonaws.com/com.images.legiteem8/stars/stars-3.jpg==1981;;https://s3.amazonaws.com/com.images.legiteem8/stars/stars-4.jpg==1982;;https://s3.amazonaws.com/com.images.legiteem8/stars/stars-5.jpg==1987;;https://s3.amazonaws.com/com.images.legiteem8/stars/stars-6.jpg==1987;;https://s3.amazonaws.com/com.images.legiteem8/stars/stars-7.jpg==1990;;https://s3.amazonaws.com/com.images.legiteem8/stars/stars-8.jpg==1994;;https://s3.amazonaws.com/com.images.legiteem8/stars/stars-9.jpg==1994",
"images": [
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/stars/stars-1.jpg",
"year": "1980"
},
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/stars/stars-2.jpg",
"year": "1981"
},
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/stars/stars-3.jpg",
"year": "1990"
},
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/stars/stars-4.jpg",
"year": "1994"
},
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/stars/stars-5.jpg",
"year": "1982"
},
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/stars/stars-6.jpg",
"year": "1987"
},
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/stars/stars-7.jpg",
"year": "1987"
},
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/stars/stars-8.jpg",
"year": "1994"
},
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/stars/stars-9.jpg",
"year": "1980"
}
]
},
{
"id": 12,
"name": "Signal T-Shirt Tags",
"year_start": "1977",
"year_end": "1994",
"category": null,
"brand_id": null,
"status": 1,
"created_at": "2024-12-10T13:27:40.000Z",
"updated_at": "2024-12-10T13:27:40.000Z",
"images_and_years": "https://s3.amazonaws.com/com.images.legiteem8/signal/signal-1.jpg==1977;;https://s3.amazonaws.com/com.images.legiteem8/signal/signal-2.jpg==1979;;https://s3.amazonaws.com/com.images.legiteem8/signal/signal-3.jpg==1980;;https://s3.amazonaws.com/com.images.legiteem8/signal/signal-4.jpg==1984;;https://s3.amazonaws.com/com.images.legiteem8/signal/signal-5.jpg==1991;;https://s3.amazonaws.com/com.images.legiteem8/signal/signal-6.jpg==1992;;https://s3.amazonaws.com/com.images.legiteem8/signal/signal-7.jpg==1992;;https://s3.amazonaws.com/com.images.legiteem8/signal/signal-8.jpg==1994;;https://s3.amazonaws.com/com.images.legiteem8/signal/signal-9.jpg==1994",
"images": [
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/signal/signal-1.jpg",
"year": "1977"
},
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/signal/signal-2.jpg",
"year": "1980"
},
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/signal/signal-3.jpg",
"year": "1992"
},
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/signal/signal-4.jpg",
"year": "1994"
},
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/signal/signal-5.jpg",
"year": "1984"
},
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/signal/signal-6.jpg",
"year": "1991"
},
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/signal/signal-7.jpg",
"year": "1992"
},
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/signal/signal-8.jpg",
"year": "1979"
},
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/signal/signal-9.jpg",
"year": "1994"
}
]
},
{
"id": 13,
"name": "Sportswear T-Shirt Tags",
"year_start": "1968",
"year_end": "1990",
"category": null,
"brand_id": null,
"status": 1,
"created_at": "2024-12-10T13:28:06.000Z",
"updated_at": "2024-12-10T13:28:06.000Z",
"images_and_years": "https://s3.amazonaws.com/com.images.legiteem8/sportswear/sportswear-1.jpg==1968;;https://s3.amazonaws.com/com.images.legiteem8/sportswear/sportswear-2.jpg==1974;;https://s3.amazonaws.com/com.images.legiteem8/sportswear/sportswear-3.jpg==1975;;https://s3.amazonaws.com/com.images.legiteem8/sportswear/sportswear-4.jpg==1978;;https://s3.amazonaws.com/com.images.legiteem8/sportswear/sportswear-5.jpg==1978;;https://s3.amazonaws.com/com.images.legiteem8/sportswear/sportswear-6.jpg==1980;;https://s3.amazonaws.com/com.images.legiteem8/sportswear/sportswear-7.jpg==1980;;https://s3.amazonaws.com/com.images.legiteem8/sportswear/sportswear-8.jpg==1981;;https://s3.amazonaws.com/com.images.legiteem8/sportswear/sportswear-9.jpg==1981;;https://s3.amazonaws.com/com.images.legiteem8/sportswear/sportswear-10.jpg==1982;;https://s3.amazonaws.com/com.images.legiteem8/sportswear/sportswear-11.jpg==1983;;https://s3.amazonaws.com/com.images.legiteem8/sportswear/sportswear-12.jpg==1984;;https://s3.amazonaws.com/com.images.legiteem8/sportswear/sportswear-13.jpg==1984;;https://s3.amazonaws.com/com.images.legiteem8/sportswear/sportswear-14.jpg==1985;;https://s3.amazonaws.com/com.images.legiteem8/sportswear/sportswear-15.jpg==1985;;https://s3.amazonaws.com/com.images.legiteem8/sportswear/sportswear-16.jpg==1990",
"images": [
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/sportswear/sportswear-1.jpg",
"year": "1981"
},
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/sportswear/sportswear-2.jpg",
"year": "1982"
},
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/sportswear/sportswear-3.jpg",
"year": "1983"
},
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/sportswear/sportswear-4.jpg",
"year": "1984"
},
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/sportswear/sportswear-5.jpg",
"year": "1984"
},
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/sportswear/sportswear-6.jpg",
"year": "1985"
},
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/sportswear/sportswear-7.jpg",
"year": "1985"
},
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/sportswear/sportswear-8.jpg",
"year": "1990"
},
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/sportswear/sportswear-9.jpg",
"year": "1981"
},
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/sportswear/sportswear-10.jpg",
"year": "1968"
},
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/sportswear/sportswear-11.jpg",
"year": "1974"
},
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/sportswear/sportswear-12.jpg",
"year": "1975"
},
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/sportswear/sportswear-13.jpg",
"year": "1978"
},
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/sportswear/sportswear-14.jpg",
"year": "1978"
},
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/sportswear/sportswear-15.jpg",
"year": "1980"
},
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/sportswear/sportswear-16.jpg",
"year": "1980"
}
]
},
{
"id": 14,
"name": "Stedman & Hi Cru T-Shirt Tags ",
"year_start": "1971",
"year_end": "1997",
"category": null,
"brand_id": null,
"status": 1,
"created_at": "2024-12-10T13:28:36.000Z",
"updated_at": "2024-12-10T13:28:36.000Z",
"images_and_years": "https://s3.amazonaws.com/com.images.legiteem8/stedman/stedman-1.jpg==1971;;https://s3.amazonaws.com/com.images.legiteem8/stedman/stedman-2.jpg==1974;;https://s3.amazonaws.com/com.images.legiteem8/stedman/stedman-3.jpg==1977;;https://s3.amazonaws.com/com.images.legiteem8/stedman/stedman-4.jpg==1978;;https://s3.amazonaws.com/com.images.legiteem8/stedman/stedman-5.jpg==1981;;https://s3.amazonaws.com/com.images.legiteem8/stedman/stedman-6.jpg==1985;;https://s3.amazonaws.com/com.images.legiteem8/stedman/stedman-7.jpg==1988;;https://s3.amazonaws.com/com.images.legiteem8/stedman/stedman-8.jpg==1989;;https://s3.amazonaws.com/com.images.legiteem8/stedman/stedman-9.jpg==1990",
"images": [
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/stedman/stedman-1.jpg",
"year": "1971"
},
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/stedman/stedman-2.jpg",
"year": "1974"
},
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/stedman/stedman-3.jpg",
"year": "1977"
},
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/stedman/stedman-4.jpg",
"year": "1978"
},
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/stedman/stedman-5.jpg",
"year": "1981"
},
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/stedman/stedman-6.jpg",
"year": "1985"
},
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/stedman/stedman-7.jpg",
"year": "1988"
},
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/stedman/stedman-8.jpg",
"year": "1989"
},
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/stedman/stedman-9.jpg",
"year": "1997"
}
]
},
{
"id": 15,
"name": "Tennessee River T-Shirt Tags",
"year_start": "1984",
"year_end": "2010",
"category": null,
"brand_id": null,
"status": 1,
"created_at": "2024-12-10T13:29:19.000Z",
"updated_at": "2024-12-10T13:29:19.000Z",
"images_and_years": "https://s3.amazonaws.com/com.images.legiteem8/tennessee/tennessee-1.jpg==1984-1992;;https://s3.amazonaws.com/com.images.legiteem8/tennessee/tennessee-2.jpg==1988-1993;;https://s3.amazonaws.com/com.images.legiteem8/tennessee/tennessee-3.jpg==1988-1994;;https://s3.amazonaws.com/com.images.legiteem8/tennessee/tennessee-4.jpg==1993-1998;;https://s3.amazonaws.com/com.images.legiteem8/tennessee/tennessee-5.jpg==1993-2000;;https://s3.amazonaws.com/com.images.legiteem8/tennessee/tennessee-6.jpg==1997-2001;;https://s3.amazonaws.com/com.images.legiteem8/tennessee/tennessee-7.jpg==1999-2001;;https://s3.amazonaws.com/com.images.legiteem8/tennessee/tennessee-8.jpg==2000-2010",
"images": [
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/tennessee/tennessee-1.jpg",
"year": "1984-1992"
},
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/tennessee/tennessee-2.jpg",
"year": "1988-1993"
},
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/tennessee/tennessee-3.jpg",
"year": "1988-1994"
},
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/tennessee/tennessee-4.jpg",
"year": "1993-2000"
},
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/tennessee/tennessee-5.jpg",
"year": "1993-1998"
},
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/tennessee/tennessee-6.jpg",
"year": "1997-2001"
},
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/tennessee/tennessee-7.jpg",
"year": "1999-2001"
},
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/tennessee/tennessee-8.jpg",
"year": "2000-2010"
}
]
},
{
"id": 16,
"name": "Wild Oats T-Shirt Tags ",
"year_start": "1984",
"year_end": "1997",
"category": null,
"brand_id": null,
"status": 1,
"created_at": "2024-12-10T13:29:51.000Z",
"updated_at": "2024-12-10T13:29:51.000Z",
"images_and_years": "https://s3.amazonaws.com/com.images.legiteem8/wild_oats/wild_oats-1.jpg==1984;;https://s3.amazonaws.com/com.images.legiteem8/wild_oats/wild_oats-2.jpg==1990;;https://s3.amazonaws.com/com.images.legiteem8/wild_oats/wild_oats-3.jpg==1992;;https://s3.amazonaws.com/com.images.legiteem8/wild_oats/wild_oats-4.jpg==1993;;https://s3.amazonaws.com/com.images.legiteem8/wild_oats/wild_oats-5.jpg==1995;;https://s3.amazonaws.com/com.images.legiteem8/wild_oats/wild_oats-6.jpg==1996;;https://s3.amazonaws.com/com.images.legiteem8/wild_oats/wild_oats-7.jpg==1997;;https://s3.amazonaws.com/com.images.legiteem8/wild_oats/wild_oats-8.jpg==1997",
"images": [
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/wild_oats/wild_oats-1.jpg",
"year": "1984"
},
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/wild_oats/wild_oats-2.jpg",
"year": "1992"
},
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/wild_oats/wild_oats-3.jpg",
"year": "1990"
},
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/wild_oats/wild_oats-4.jpg",
"year": "1995"
},
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/wild_oats/wild_oats-5.jpg",
"year": "1995"
},
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/wild_oats/wild_oats-6.jpg",
"year": "1993"
},
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/wild_oats/wild_oats-7.jpg",
"year": "1996"
},
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/wild_oats/wild_oats-8.jpg",
"year": "1997"
}
]
},
{
"id": 17,
"name": "Winterland T-Shirt Tags",
"year_start": "1982",
"year_end": "2002",
"category": null,
"brand_id": null,
"status": 1,
"created_at": "2024-12-10T13:30:20.000Z",
"updated_at": "2024-12-10T13:30:20.000Z",
"images_and_years": "https://s3.amazonaws.com/com.images.legiteem8/winterland/winterland-1.jpg==1982-1988;;https://s3.amazonaws.com/com.images.legiteem8/winterland/winterland-2.jpg==1987-1992;;https://s3.amazonaws.com/com.images.legiteem8/winterland/winterland-3.jpg==1992-1997;;https://s3.amazonaws.com/com.images.legiteem8/winterland/winterland-4.jpg==1994-1997;;https://s3.amazonaws.com/com.images.legiteem8/winterland/winterland-5.jpg==1997-2001;;https://s3.amazonaws.com/com.images.legiteem8/winterland/winterland-6.jpg==1998-2001;;https://s3.amazonaws.com/com.images.legiteem8/winterland/winterland-7.jpg==2001-2008;;https://s3.amazonaws.com/com.images.legiteem8/winterland/winterland-8.jpg==2005-2008",
"images": [
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/winterland/winterland-1.jpg",
"year": "1982-1988"
},
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/winterland/winterland-2.jpg",
"year": "1987-1992"
},
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/winterland/winterland-3.jpg",
"year": "1992-1997"
},
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/winterland/winterland-4.jpg",
"year": "1994-1997"
},
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/winterland/winterland-5.jpg",
"year": "1997-2001"
},
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/winterland/winterland-6.jpg",
"year": "1998-2001"
},
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/winterland/winterland-7.jpg",
"year": "2001-2008"
},
{
"image": "https://s3.amazonaws.com/com.images.legiteem8/winterland/winterland-8.jpg",
"year": "2001-2008"
}
]
}
]
}
+56
View File
@@ -0,0 +1,56 @@
# DS Task Tag Scan API
Simple API for clothing tag identification and similarity search.
## Endpoints
### POST `/get_tag`
Analyze a clothing tag image.
**Request:**
```json
{
"image_url": "https://example.com/tag.jpg"
}
```
**Response:**
```json
{
"success": true,
"results": [
{
"tag": "Nike T-Shirt Tags",
"year_start": "1995",
"year_end": "2006"
}
],
"metadata": {
"identified_brand": "nike",
"processing_time_seconds": 3.6
}
}
```
### GET `/status`
Check if the system is running.
**Response:**
```json
{
"status": "healthy"
}
```
## Usage
```bash
curl -X POST http://localhost:5000/get_tag \
-H "Content-Type: application/json" \
-d '{"image_url": "https://example.com/tag.jpg"}'
```
## Notes
- Response time: ~3-5 seconds
- Supports JPEG, PNG images
- Returns text matches and similar images
+158
View File
@@ -0,0 +1,158 @@
# DS Task: Tag Scan System
## Project Overview
DS Task Tag Scan is an AI-powered clothing tag identification and similarity search system that analyzes clothing tag images, identifies brands using computer vision, and finds similar tags from a database. The system uses advanced AI techniques including image embeddings and text similarity to provide accurate tag matching and recommendations.
## Features
* **Tag Identification**: Uses computer vision to identify clothing tag brands from images
* **Text-Based Matching**: Implements TF-IDF and cosine similarity for tag name matching
* **Image Similarity Search**: Uses CLIP embeddings to find visually similar tag images
* **LLM Enhancement**: Optional LLM analysis for improved similarity filtering
* **Metadata Extraction**: Provides appraisal values, years, and status information for similar tags
## Tech Stack
* **Computer Vision**: CLIP or ViT models (free from Hugging Face)
* **Text Processing**: TF-IDF vectorization and cosine similarity
* **LLM Enhancement**: Groq Llama4 Scout/Maverick (optional)
* **Backend**: Flask
* **Image Processing**: Pillow, OpenCV
* **Data Processing**: Pandas, NumPy, scikit-learn
## File Structure
```
ds_task/
│-- backend/
│ │-- app.py # Main Flask application
│ │-- tag_identification.py # Tag identification using vision models
│ │-- tag_match.py # Text-based tag matching using TF-IDF
│ │-- image_similarity.py # CLIP-based image similarity search
│ │-- config.py # Configuration settings
│ │-- requirements.txt # Dependencies
│-- data/
│ │-- tag_guides_clean.json # Tag database with historical images
│ │-- expert_data.csv # Expert dataset with tag images and metadata
│ │-- community_data.csv # Community dataset with tag images and metadata
│-- docs/
│ │-- README.md # Project documentation
│ │-- API_Documentation.md # API details
│-- .env # Environment variables
│-- .gitignore # Git ignore file
│-- LICENSE # License information
```
## Setup & Installation
### 1. Clone the Repository
```bash
git clone <repository-url>
cd ds_task
```
### 2. Set Up the Backend
```bash
cd backend
pip install -r requirements.txt
python app.py
```
## Tag Scan Workflow
The system processes clothing tag images through several stages:
1. **Image Upload**: Receive tag image URL
2. **Tag Identification**: Use vision model to identify brand/tag
3. **Text Matching**: Match identified tag against database using TF-IDF
4. **Similarity Search**: Find similar images using CLIP embeddings
5. **Result Aggregation**: Return similar images with metadata
### **Example Tag Identification Code (Python)**
```python
from transformers import CLIPProcessor, CLIPModel
import torch
def identify_tag(image_url):
model = CLIPModel.from_pretrained("openai/clip-vit-base-patch16")
processor = CLIPProcessor.from_pretrained("openai/clip-vit-base-patch16")
# Process image and get embeddings
image = load_image(image_url)
inputs = processor(images=image, return_tensors="pt")
image_features = model.get_image_features(**inputs)
# Compare with tag database
return find_best_match(image_features)
```
## API Endpoints
* `POST /get_tag`: Upload image URL and get similar tag images with metadata
* `GET /status`: Health check endpoint
### Example Request
```json
{
"image_url": "https://example.com/tag_image.jpg"
}
```
### Example Response
```json
{
"results": [
{
"tag": "Jerzees T-Shirt Tags",
"year_start": "1985",
"year_end": "1998"
},
{
"similar_images": ["url1", "url2"],
"appraisal_value": [150.0, 75.0],
"years": ["1998", "1997"],
"status": ["public", "private"]
}
]
}
```
## Key Implementation Tasks
1. **Tag Identification**: Implement vision-based tag recognition using free models
2. **Text Matching**: Use TF-IDF and cosine similarity for tag matching
3. **Image Similarity**: Implement CLIP-based image embedding and search
4. **LLM Enhancement**: Add optional LLM analysis for better results
5. **Data Processing**: Handle image downloads and metadata extraction
6. **API Design**: Create clean Flask endpoints with proper error handling
## Data Sources
* `tag_guides_clean.json`: Contains tag information with historical images and year ranges
* `expert_data.csv`: Contains tag images with appraisal values, status, and metadata
* `community_data.csv`: Contains tag images with appraisal values, status, and metadata
## Vision Model Options
You can use any of these free models from Hugging Face:
- CLIP (image-text matching)
- ViT (image classification)
- EasyOCR (text extraction)
- ResNet (image classification)
## What Success Looks Like
- ✅ Can extract text from tag images
- ✅ Can match brands using TF-IDF similarity
- ✅ Can find visually similar images
- ✅ Optional: LLM enhances similarity analysis
- ✅ Returns properly formatted JSON response
- ✅ Response time under 60 seconds