<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Originate Soft Pvt Ltd</title>
    <description>The latest articles on DEV Community by Originate Soft Pvt Ltd (@originatesoft_kolkata_59c).</description>
    <link>https://dev.to/originatesoft_kolkata_59c</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4168637%2F16280f7c-6c4c-4801-afe7-34ce31b9a4b9.png</url>
      <title>DEV Community: Originate Soft Pvt Ltd</title>
      <link>https://dev.to/originatesoft_kolkata_59c</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/originatesoft_kolkata_59c"/>
    <language>en</language>
    <item>
      <title>How to Build an AI-Based Personalized Fashion Platform (Skin Tone, Color Matching and Recommendations)</title>
      <dc:creator>Originate Soft Pvt Ltd</dc:creator>
      <pubDate>Wed, 07 Oct 2026 11:50:03 +0000</pubDate>
      <link>https://dev.to/originatesoft_kolkata_59c/how-to-build-an-ai-based-personalized-fashion-platform-skin-tone-color-matching-and-1m20</link>
      <guid>https://dev.to/originatesoft_kolkata_59c/how-to-build-an-ai-based-personalized-fashion-platform-skin-tone-color-matching-and-1m20</guid>
      <description>&lt;p&gt;Most "personalized" fashion sites are really "people who bought this also bought that." That's fine, but it doesn't answer the question a shopper actually has: what will look good on me?&lt;br&gt;
A proper personalized fashion platform tries to answer that one. It reads a few signals about the person (skin tone, undertone, size, style leanings, past behavior), matches them against what's in the catalog, and ranks products accordingly.&lt;br&gt;
Founders are circling this idea too. One r/Startup_Ideas thread describes an AI fashion assistant that suggests clothes by skin tone, body type and fit, offers virtual try-on, and aims to recommend what is suitable and correctly sized, not just what's trending. That's the shape of product this article is about, so we'll go through each piece.&lt;br&gt;
This guide walks through how to build that: the architecture, the skin tone pipeline, the color-matching logic, recommendations with embeddings, and the privacy and fairness work people tend to skip. There's code for the core pieces.&lt;br&gt;
One honest note before we start. Matching clothes to complexion is a styling heuristic, not a law of nature. Build it as "colors that tend to flatter you" with an easy override, never as "this color is wrong for you." That framing will shape a lot of the decisions below.&lt;/p&gt;

&lt;h2&gt;
  
  
  The architecture at a glance
&lt;/h2&gt;

&lt;p&gt;Selfie (processed on device)&lt;br&gt;
   -&amp;gt; face landmarks -&amp;gt; skin patches -&amp;gt; Lab color -&amp;gt; tone + undertone + confidence&lt;br&gt;
                                                              |&lt;br&gt;
Catalog images                                                |&lt;br&gt;
   -&amp;gt; garment color extraction + FashionCLIP embeddings       |&lt;br&gt;
   -&amp;gt; vector index                                            v&lt;br&gt;
User profile (tone, size, style, history) -&amp;gt; candidate retrieval -&amp;gt; re-ranker -&amp;gt; personalized feed&lt;br&gt;
                                                (embeddings)      (color harmony + behavior)&lt;br&gt;
Two pipelines meet in the middle. One understands the person, one understands the products, and the ranker decides which products to show to whom.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1: Understand your catalog first
&lt;/h2&gt;

&lt;p&gt;Skin tone detection gets the attention, but the catalog is where most projects quietly fail. If your product data is messy, the smartest matching engine in the world has nothing to match against.&lt;br&gt;
For each product you want:&lt;br&gt;
• Clean attributes: category, fit, fabric, pattern, occasion, size availability.&lt;br&gt;
• Real garment colors: not the marketing name ("Midnight Mist"), but measured color values.&lt;br&gt;
• Image embeddings: so you can search and compare visually.&lt;br&gt;
To get garment colors, segment the garment from the background and from any model's skin (a clothing parser or a segmentation model both work), then cluster the remaining pixels in Lab space.&lt;br&gt;
import numpy as np&lt;br&gt;
from skimage import color&lt;br&gt;
from sklearn.cluster import KMeans&lt;/p&gt;

&lt;p&gt;def dominant_colors(garment_rgb_pixels, k=3):&lt;br&gt;
    """garment_rgb_pixels: (N, 3) uint8 array of garment-only pixels."""&lt;br&gt;
    rgb = garment_rgb_pixels.astype(np.float32) / 255.0&lt;br&gt;
    lab = color.rgb2lab(rgb.reshape(-1, 1, 3)).reshape(-1, 3)&lt;br&gt;
    km = KMeans(n_clusters=k, n_init=10, random_state=0).fit(lab)&lt;br&gt;
    counts = np.bincount(km.labels_, minlength=k)&lt;br&gt;
    order = np.argsort(-counts)&lt;br&gt;
    # return cluster centers (L*, a*, b*) with their share of the garment&lt;br&gt;
    return [(km.cluster_centers_[i], counts[i] / counts.sum()) for i in order]&lt;br&gt;
Why Lab and not RGB? Because distances in CIELAB roughly follow how humans perceive color differences. RGB distances don't, and that matters when you start scoring "how different is this shirt from this person's skin."&lt;br&gt;
Product photos also vary in lighting and editing. Studio shots are usually consistent within a brand, but if you aggregate several brands, expect color drift. Store the measured color, but keep the seller's color name too, and consider letting merchants correct it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2: Detect skin tone from a photo
&lt;/h2&gt;

&lt;p&gt;Here's the pipeline most teams end up with:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; Detect the face and landmarks. MediaPipe Face Mesh runs in the browser and on phones, which matters for privacy (more on that later).&lt;/li&gt;
&lt;li&gt; Pick skin regions. Cheeks and forehead are the usual choice. Skip eyes, lips, eyebrows, beard, and anything near the hairline.&lt;/li&gt;
&lt;li&gt; Remove bad pixels. Specular highlights and deep shadows will pull your estimate around.&lt;/li&gt;
&lt;li&gt; Correct white balance as best you can.&lt;/li&gt;
&lt;li&gt; Convert to Lab and take a robust statistic (the median).&lt;/li&gt;
&lt;li&gt; Compute tone and undertone, plus a confidence score.
import numpy as np
from skimage import color&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;def skin_lab(skin_pixels_rgb):&lt;br&gt;
    """skin_pixels_rgb: (N, 3) uint8 pixels sampled from cheeks/forehead."""&lt;br&gt;
    rgb = skin_pixels_rgb.astype(np.float32) / 255.0&lt;br&gt;
    lab = color.rgb2lab(rgb.reshape(-1, 1, 3)).reshape(-1, 3)&lt;br&gt;
    L = lab[:, 0]&lt;br&gt;
    lo, hi = np.percentile(L, [15, 85])         # drop deep shadows and highlights&lt;br&gt;
    kept = lab[(L &amp;gt;= lo) &amp;amp; (L &amp;lt;= hi)]&lt;br&gt;
    return np.median(kept, axis=0)              # (L*, a*, b*)&lt;/p&gt;

&lt;p&gt;def ita_degrees(L, b):&lt;br&gt;
    """Individual Typology Angle, a standard skin-lightness measure."""&lt;br&gt;
    return np.degrees(np.arctan2(L - 50.0, b))&lt;br&gt;
What ITA gives you&lt;br&gt;
The Individual Typology Angle is a number computed from the L* and b* channels. It's widely used in dermatology research to estimate skin tone from images, and it correlates with how light or dark skin appears. The literature groups it roughly into very light, light, intermediate, tan, brown and dark bands (see this paper on estimating skin tone in dermatology datasets for how it's used in practice).&lt;br&gt;
What I'd suggest: use ITA as a continuous feature, not as a label. Don't hard-bucket users and then show them a bucket name.&lt;br&gt;
Which scale to show users&lt;br&gt;
If you do show a scale, use one built for appearance. Google's Monk Skin Tone Scale has ten shades and was released to help test AI systems for bias, which also makes it a good fit for the evaluation work later in this article. It's more granular than the older six-type Fitzpatrick scale, which describes how skin reacts to sun exposure rather than how it looks, so I'd skip Fitzpatrick for styling.&lt;br&gt;
There's no official, validated mapping from ITA values to the ten Monk shades. So don't pretend there is. Let the model suggest a shade and have the user confirm it with a swatch picker.&lt;br&gt;
Undertone&lt;br&gt;
Undertone (warm, cool, neutral) is harder than depth. A rough photo-based signal comes from the hue angle in the a*/b* plane, where more yellow reads warmer and more red or pink reads cooler.&lt;br&gt;
def undertone_from_lab(a, b, warm_cut=58.0, cool_cut=50.0):&lt;br&gt;
    """Cutoffs are placeholders. Calibrate them on labeled data from your own users."""&lt;br&gt;
    hue = np.degrees(np.arctan2(b, a))&lt;br&gt;
    if hue &amp;gt;= warm_cut:&lt;br&gt;
        return "warm"&lt;br&gt;
    if hue &amp;lt;= cool_cut:&lt;br&gt;
        return "cool"&lt;br&gt;
    return "neutral"&lt;br&gt;
Those cutoffs are made up for the example, and I mean that literally: tune them on real, consented, labeled data from your audience. Because a photo alone is shaky here, combine it with a quick question or two ("Does gold or silver jewelry look better on you?"). Two weak signals together beat one weak signal.&lt;br&gt;
Where this breaks in the real world&lt;br&gt;
Almost every failure I'd expect here comes from the input, not the model:&lt;br&gt;
• Lighting: warm bulbs, window backlight, and phone night mode all shift the result.&lt;br&gt;
• White balance and filters: beauty filters and auto-processing change skin color before you ever see it.&lt;br&gt;
• Makeup and tan: you'd be measuring what's on the skin today.&lt;br&gt;
• Shadows and facial hair: these bias the sampled pixels.&lt;br&gt;
• Cheap cameras: noise and heavy compression.&lt;br&gt;
The practical answer: show a short capture guide ("face a window, no filter"), compute a confidence score (pixel variance, number of usable pixels, lighting checks), and fall back to the manual swatch picker when confidence is low. Never silently guess.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 3: Build the color-matching engine
&lt;/h2&gt;

&lt;p&gt;Now you have a person (Lab values, undertone) and a garment (dominant colors). You need a score.&lt;br&gt;
Start with rules. They're explainable, easy to debug, and they give you something to ship before you have any behavioral data. Three signals are a reasonable start:&lt;br&gt;
• Contrast: how far the garment is from the skin tone (CIEDE2000 is the standard perceptual distance).&lt;br&gt;
• Chroma: how vivid the garment color is.&lt;br&gt;
• Undertone fit: whether the garment's hue sits on the warm or cool side.&lt;br&gt;
import numpy as np&lt;br&gt;
from skimage import color&lt;/p&gt;

&lt;p&gt;def harmony_score(skin_lab, garment_lab, undertone):&lt;br&gt;
    """Return a 0..1 score. Weights are starting points. Learn them from feedback."""&lt;br&gt;
    d_e = color.deltaE_ciede2000(skin_lab[None, None, :], garment_lab[None, None, :])[0, 0]&lt;br&gt;
    contrast = np.clip(d_e / 60.0, 0, 1)&lt;br&gt;
    chroma = np.hypot(garment_lab[1], garment_lab[2])&lt;br&gt;
    vivid = np.clip(chroma / 80.0, 0, 1)&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;garment_hue = np.degrees(np.arctan2(garment_lab[2], garment_lab[1])) % 360
warm_side = np.cos(np.radians(garment_hue - 60))   # +1 yellow/orange, -1 blue/green
if undertone == "warm":
    fit = warm_side
elif undertone == "cool":
    fit = -warm_side
else:
    fit = 0.0

return 0.4 * contrast + 0.2 * vivid + 0.4 * (0.5 + 0.5 * fit)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Be clear-eyed about what this is. The popular "seasonal color analysis" (spring, summer, autumn, winter) is a stylist tradition, not a validated science, and plenty of people look great in colors a rule says they shouldn't wear. High contrast also isn't universally "better"; some people prefer soft, low-contrast outfits.&lt;br&gt;
So treat the rule score as one feature, not the verdict. Once you have click, save, purchase and return data, feed harmony_score into a learned ranker and let behavior decide how much it matters for each user. Returns tagged "color not as expected" or "didn't suit me" are especially valuable training signal.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 4: Recommendations with embeddings
&lt;/h2&gt;

&lt;p&gt;Color match is only one part of "what will this person like." For the rest you need visual and semantic similarity.&lt;br&gt;
FashionCLIP is a CLIP model fine-tuned on fashion data (the original work came from Farfetch's research team), and it's available on Hugging Face. It maps product images and text into the same vector space, so you can search "linen shirt dress" and also find products visually similar to one a user saved.&lt;br&gt;
import torch&lt;br&gt;
from transformers import CLIPModel, CLIPProcessor&lt;/p&gt;

&lt;p&gt;model = CLIPModel.from_pretrained("patrickjohncyh/fashion-clip")&lt;br&gt;
processor = CLIPProcessor.from_pretrained("patrickjohncyh/fashion-clip")&lt;/p&gt;

&lt;p&gt;def embed_images(pil_images):&lt;br&gt;
    inputs = processor(images=pil_images, return_tensors="pt")&lt;br&gt;
    with torch.no_grad():&lt;br&gt;
        emb = model.get_image_features(**inputs)&lt;br&gt;
    return emb / emb.norm(dim=-1, keepdim=True)        # normalize for cosine search&lt;/p&gt;

&lt;p&gt;def embed_text(texts):&lt;br&gt;
    inputs = processor(text=texts, return_tensors="pt", padding=True)&lt;br&gt;
    with torch.no_grad():&lt;br&gt;
        emb = model.get_text_features(**inputs)&lt;br&gt;
    return emb / emb.norm(dim=-1, keepdim=True)&lt;br&gt;
Store the vectors in pgvector (if you're already on Postgres) or FAISS, and use a two-stage setup:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; Candidate retrieval: hard filters first (in stock in the user's size, price range, category), then nearest neighbors to the user's taste vector (an average of items they've saved or bought).&lt;/li&gt;
&lt;li&gt; Re-ranking: a learning-to-rank model (LightGBM's LambdaRank is a solid, boring choice) over features like embedding similarity, harmony_score, price fit, brand affinity, popularity and recency.
Cold start is the real problem with a new user. Use a short onboarding quiz (styles, occasions, budget), the confirmed skin tone, and popularity within similar profiles until behavior data builds up.
Measure what matters: click-through, add-to-cart, conversion and, for fashion especially, return rate. A recommender that lifts clicks but also lifts returns isn't working.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Step 5: Body type, fit and size
&lt;/h2&gt;

&lt;p&gt;Skin tone is the visible feature, but "will this actually fit?" is where returns come from. It's a separate problem from color, and it needs its own data.&lt;br&gt;
• Garment measurements, not just size labels. An "M" means different things in different brands. For each size, store measured dimensions (chest, waist, shoulder, length) where you can get them. Many merchants don't have these, so make collecting them part of seller onboarding.&lt;br&gt;
• Start with a short questionnaire. Height, a weight range, the size the person usually wears in a couple of brands, and a fit preference (snug, regular, relaxed). It's cheap, private and a workable baseline.&lt;br&gt;
• Learn from outcomes. Purchases that were kept, and returns tagged "too small" or "too large", are your best training data. A size recommender is often framed as predicting the size a person will keep, given their profile and the brand's history.&lt;br&gt;
• Photo-based body measurement comes later. Pose estimation (MediaPipe Pose, for example) and body-shape models can estimate proportions from a photo. Accuracy depends on clothing, camera angle and pose, and full-body photos are very sensitive, so keep it optional and on-device, same rule as the skin tone photo.&lt;br&gt;
• Be careful with "body type" labels. Shapes like "pear" or "rectangle" are styling shorthand, not measurements, and plenty of people dislike being labeled. Offer them as optional, editable hints and let measurements and behavior do the real work.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 6 (later): Virtual try-on
&lt;/h2&gt;

&lt;p&gt;Virtual try-on is the feature everyone wants in the demo. Diffusion-based approaches such as IDM-VTON (from an ECCV 2024 paper on try-on "in the wild") can render a garment onto a person's photo with convincing detail.&lt;br&gt;
It's also the heaviest part of the stack: GPU inference, noticeable latency, per-image cost, and a stricter privacy burden because you're handling full-body photos. My suggestion is to launch without it. Ship outfit boards and color-matched picks first, then add try-on once the core loop is earning its keep.&lt;br&gt;
If you want users to share try-on images with friends or family for opinions, treat that as its own feature with its own risks. Use expiring links, label images as AI-generated, let users switch sharing off, and require them to confirm the uploaded photo is of themselves. Without that, you've built a tool that can be misused on other people's photos.&lt;/p&gt;

&lt;h2&gt;
  
  
  Fairness: test across skin tones, not on average
&lt;/h2&gt;

&lt;p&gt;A skin tone feature that works well for lighter skin and poorly for darker skin isn't a minor bug. It's a broken product for a large part of your audience. So:&lt;br&gt;
• Build a consented, diverse evaluation set labeled with a scale such as Monk.&lt;br&gt;
• Report accuracy and failure rate per tone bucket, not just overall.&lt;br&gt;
• Test across lighting conditions and devices, including low-end phones.&lt;br&gt;
• Track the share of users who override the suggested tone, per bucket. A high override rate in one group is a red flag.&lt;br&gt;
• Use positive, optional language in the UI ("colors that tend to flatter") and keep the override one tap away.&lt;/p&gt;

&lt;h2&gt;
  
  
  Privacy and compliance
&lt;/h2&gt;

&lt;p&gt;Face photos are sensitive, so design to collect as little as possible:&lt;br&gt;
• Process on the device. Run face landmarks and color sampling in the browser or app so the selfie never leaves the phone.&lt;br&gt;
• Store derived values only. A few Lab numbers and an undertone label are far safer than an image.&lt;br&gt;
• Ask for clear, specific consent, and make deleting the data as easy as giving it.&lt;br&gt;
• Know your law. If you operate in India, the Digital Personal Data Protection Act and its Rules (notified in November 2025) phase in their main obligations over the following 12 to 18 months, according to this summary from Hogan Lovells. The Act expects consent that is specific and informed, and it can't be bundled with unrelated purposes. If you serve EU users, GDPR applies too. Check current dates with a lawyer, because this is moving.&lt;/p&gt;

&lt;h2&gt;
  
  
  A sensible build order
&lt;/h2&gt;

&lt;p&gt;Phase   What ships  Why this order&lt;br&gt;
1   Storefront, clean catalog, onboarding quiz with size and fit questions, manual skin tone picker Validates demand before any camera pipeline&lt;br&gt;
2   Photo-based tone and undertone detection with confidence and override   Removes friction once you know people use it&lt;br&gt;
3   Embeddings, retrieval and learned re-ranker Needs real behavior data to be worth it&lt;br&gt;
4   Virtual try-on, outfit builder  Expensive, so earn it&lt;br&gt;
A practical stack: a React or Next.js storefront plus a Flutter or React Native app, a FastAPI service for the models, Postgres with pgvector, and a small queue for batch embedding jobs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Don't rebuild the boring half
&lt;/h2&gt;

&lt;p&gt;Look back at the architecture diagram. Everything outside the recommender (catalog, size and color variants, cart, checkout, orders, returns and a mobile app) is standard commerce. It's necessary and well understood, but it's not what makes your platform different. Teams that build it all from scratch often spend months before a single user sees a color-matched recommendation.&lt;br&gt;
That's the argument for starting from a ready-made fashion storefront and putting your engineering time into the AI layer. The base does need to understand apparel (variants per size and color, collections, returns) and, just as important, give your own services a way in through APIs or custom modules.&lt;br&gt;
One option worth evaluating is a &lt;a href="https://originatesoft.com/ecommerce-software-solution/fashion-apparel-software/" rel="noopener noreferrer"&gt;ready-made fashion and apparel e-commerce software solution&lt;/a&gt; that comes with a mobile app. (Disclosure: it's from the company that publishes this account.) Whichever base you look at, ask two things before committing: can you plug in your own ranking service, and can you export product data to generate embeddings?&lt;/p&gt;

&lt;h2&gt;
  
  
  The verdict
&lt;/h2&gt;

&lt;p&gt;If I were building this today, I'd ship in this order: a clean catalog, a manual skin tone picker with a Monk-style swatch, and rule-based color matching. That alone tests whether shoppers care. Add the photo pipeline only after they do, and keep every AI suggestion optional, explainable and easy to override.&lt;br&gt;
The technology is the easy part. The hard parts are honest framing, fair performance across skin tones, and respecting the data people hand you. Get those right and the rest is engineering.&lt;br&gt;
If you've built something similar, tell us in the comments what broke first. My guess is lighting.&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;p&gt;• Estimating skin tone and effects on classification performance in dermatology datasets (ITA in practice)&lt;br&gt;
• Google's 10-shade skin tone scale (Monk Skin Tone Scale)&lt;br&gt;
• Contrastive language and vision learning of general fashion concepts (FashionCLIP) and the model on Hugging Face&lt;br&gt;
• Improving Diffusion Models for Authentic Virtual Try-on in the Wild (IDM-VTON)&lt;br&gt;
• India's DPDP Act brought into force (Hogan Lovells)&lt;br&gt;
• Building an AI based personalized fashion platform (r/Startup_Ideas) (a founder's discussion of the idea)&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;p&gt;• &lt;a href="https://arxiv.org/pdf/1910.13268" rel="noopener noreferrer"&gt;Estimating skin tone and effects on classification performance in dermatology datasets &lt;/a&gt;(ITA in practice)&lt;br&gt;
• &lt;a href="https://www.ft.lk/it-telecom-tech/Google-unveils-new-10-shade-skin-tone-scale-to-test-ai-for-bias/50-734704" rel="noopener noreferrer"&gt;Google's 10-shade skin tone scale&lt;/a&gt; (Monk Skin Tone Scale)&lt;br&gt;
• &lt;a href="https://arxiv.org/pdf/2204.03972" rel="noopener noreferrer"&gt;Contrastive language and vision learning of general fashion concepts&lt;/a&gt; (FashionCLIP) and the model on Hugging Face&lt;br&gt;
• &lt;a href="https://arxiv.org/pdf/2403.05139" rel="noopener noreferrer"&gt;Improving Diffusion Models for Authentic Virtual Try-on in the Wild&lt;/a&gt; (IDM-VTON)&lt;br&gt;
• &lt;a href="https://ca.hoganlovells.com/en/publications/indias-digital-personal-data-protection-act-2023-brought-into-force-" rel="noopener noreferrer"&gt;India's DPDP Act brought into force&lt;/a&gt; (Hogan Lovells)&lt;br&gt;
• &lt;a href="https://www.reddit.com/r/Startup_Ideas/comments/1qn94x2/building_an_ai_based_personalized_fashion/" rel="noopener noreferrer"&gt;Building an AI based personalized fashion platform (r/Startup_Ideas)&lt;/a&gt; (a founder's discussion of the idea)&lt;/p&gt;

</description>
      <category>ai</category>
      <category>machinelearning</category>
      <category>ecommerce</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
