DRAPEa / utils /fit_predictor.py
andevs's picture
Upload 18 files
9c1053c verified
Raw
History Blame Contribute Delete
2.69 kB
import torch
import numpy as np
import cv2
from transformers import AutoModelForImageClassification, AutoFeatureExtractor
class FitPredictor:
def __init__(self):
self.model_name = "facebook/dinov2-base"
self.feature_extractor = AutoFeatureExtractor.from_pretrained(self.model_name)
self.model = AutoModelForImageClassification.from_pretrained(self.model_name)
self.model.eval()
self.fit_types = ['tight', 'regular', 'loose', 'oversized']
self.fit_recommendations = {
'tight': ['Size up for comfort', 'Choose stretchy fabrics', 'Consider relaxed fit alternative'],
'regular': ['True to size', 'Standard fit works for most body types'],
'loose': ['Size down for fitted look', 'Great for layering', 'Can be styled with belt'],
'oversized': ['Intentional oversized style', 'Style with fitted pieces', 'Works well for streetwear']
}
self.size_adjustments = {
'tight': '+1',
'regular': '0',
'loose': '-1',
'oversized': '-2'
}
def predict(self, image: np.ndarray) -> dict:
inputs = self.feature_extractor(images=image, return_tensors="pt")
with torch.no_grad():
outputs = self.model(**inputs)
logits = outputs.logits
probabilities = torch.softmax(logits, dim=-1)
probs = probabilities[0].tolist()
fit_type = self.fit_types[0]
confidence = 0.5
for i, ft in enumerate(self.fit_types):
if i < len(probs):
if probs[i] > confidence:
confidence = probs[i]
fit_type = ft
recommendations = self.fit_recommendations.get(fit_type, self.fit_recommendations['regular'])
size_adjustment = self.size_adjustments.get(fit_type, '0')
return {
"fit": fit_type,
"confidence": confidence,
"recommendations": recommendations,
"size_adjustment": size_adjustment,
"body_compatibility": self._get_body_compatibility(fit_type)
}
def _get_body_compatibility(self, fit_type: str) -> dict:
compatibility = {
'tight': {'slim': 0.9, 'athletic': 0.8, 'curvy': 0.6, 'plus': 0.4},
'regular': {'slim': 0.8, 'athletic': 0.9, 'curvy': 0.8, 'plus': 0.7},
'loose': {'slim': 0.7, 'athletic': 0.8, 'curvy': 0.9, 'plus': 0.9},
'oversized': {'slim': 0.9, 'athletic': 0.7, 'curvy': 0.6, 'plus': 0.5}
}
return compatibility.get(fit_type, compatibility['regular'])