StyleLab:拍一张照片,让 AI 读懂你的色彩与形象
一个 App 走完测色 → 穿搭 → 形象试穿;背后是色彩理论、保脸换装与评测纠偏
上传一次照片,AI 帮你测色(12 季型)、配穿搭、试花纹/发色/发型/妆容/首饰——而且所有效果图都直接生成在你本人脸上。
线上体验:sg.yaoyuheng2001.me/colorstyle/app.html · 源码:github.com/piglet12138/ai-color-test
- Part 1 · App 流程体验与讲解:从用户视角走一遍,配真实截图 + AI 生成样例。
- Part 2 · 技术实现介绍:色彩理论基础、调用的 API、"保脸"换装的整套设计,以及公开人脸集评测实验。
StyleLab 被设计成一个手机 App 的样子(phone frame + 底部 5 个 Tab + 引导流),但它其实是一个纯网页,打开链接就能用。整个产品的核心理念只有一句话:


建档:只上传一次
第一次进来是引导流:欢迎页 → 上传页 → 分析中 → 色彩报告。上传页不是简单丢个文件框,而是带了一整套拍照引导,因为测色对照片质量非常敏感:面朝自然光、素颜/淡妆、关美颜、用原图、正脸露额头;有条件的话在下巴旁举一张 A4 白纸——App 会自动用它做白平衡校色。
选完图立刻显示预览,并跑一遍客户端质量门(QC):分辨率、曝光、清晰度、过曝削波——不合格会给出具体的重拍建议("太暗了,找更亮的自然光""拿稳手机等对焦"),而不是拍完传上去才发现测不准。
色彩报告:你的"形象档案"
点「AI 测色,生成档案」,几秒到十几秒后出报告——季型判定(如"柔秋 Soft Autumn",带一个真实的置信度,照片差会自动降)、个人色板(推荐 / 中性 / 避免色,都有中文名 + 精确色号)、妆容色,以及一段故意不带技术黑话的通俗解释。登录后这份档案存进服务器,下次免重传。


首页:四个入口,共用一张照片
建档完成进入首页,四张功能卡——🎨 色彩测试、👗 穿搭试穿、💇 形象测试、🗂️ 我的历史。关键在于:这四个入口全都复用建档时那一张照片,你不需要每次重传。
色彩测试海报
用你档案里的照片生成一张色彩分析大图。做法很巧妙——不是让 AI 一次画出整张海报(那样文字会糊、脸会不一致、颜色也不准),而是:GPT-5 看照片出完整的色彩 JSON(准)→ 并行生成"色带":同一个你、并排穿多种颜色(脸一致、颜色按序、无文字)→ 前端拼版导出。下面这张就是真实生成的一条推荐色色带——六件不同颜色的针织衫,同一张脸、同一个人:
穿搭试穿:把衣服"穿"到你身上
这是最出效果的部分。AI 根据你的季型和色板给 2-3 套成套造型(配色 + 单品 + 小红书式点评),然后把这套穿搭直接生成在你本人的照片上。下面三张是真实的 AI 试穿输出——严格保留脸型/发型/体态,只换身上的衣服:



除了纯换装,还有一个默认开启的氛围感模式——不只是换衣服,而是把你放进一张贴合季型的氛围大片里。柔秋会给你咖啡馆的黄金暖光、慵懒碎发、松弛表情、暖棕调,身份保持得很好,效果远胜纯灰底证件照:
形象测试实验室 · 我的
一次上传,五种测试:花纹 / 发色 / 发型 / 妆容 / 首饰。点任意一项,AI 先推荐适合你的若干选项(带理由),再生成一张"同一个你、并排展示各选项"的对比图。妆容和首饰会按性别给不同方案。「我的」里所有结果按类型汇总、可筛选、可点开看详情,历史图片长期保存;勾选过匿名数据贡献的还能一键撤回删除。


整个后端是一个零依赖的 Node 文件(server.mjs,纯 node:http + JSON 存盘,不跑 npm install),前端是原生 JS。所有 AI 能力都走同一个 OpenAI 兼容反代:GPT-5(多模态,看图 + 推理)负责所有"判断/文字",gpt-image 负责所有"生图/换装"。
色彩理论基础:四季十二型
产品的理论内核是季节性色彩分析(Seasonal Color Analysis)里的 12 季型体系。它把人按三个正交维度分类:
- 冷暖(Undertone):cool / warm / neutral——看肤色、唇色、血管泛粉泛蓝(冷)还是泛黄泛金(暖);
- 明度(Value):浅 / 中 / 深;
- 纯度(Chroma):清透鲜艳 / 柔和浑浊。
三轴组合落到春/夏/秋/冬四大族、每族三型共 12 个季型(浅春、暖春、亮春、浅夏、冷夏、柔夏、柔秋、暖秋、深秋、亮冬、冷冬、深冬)。每个季型对应一套"显气色"的色板和一套"显疲惫"的避免色。
我把这套体系固化成一份参考数据库(presets.mjs):12 季型每个都带三轴标注 + 6 个代表色(中文名 + 精确 hex)+ 避免色。这份 KB 会被压缩成紧凑字符串注入到 prompt 里,让 GPT-5 的分类必须从 12 季型里选、推荐色优先采用标准代表色——保证输出落在专业体系内、色号一致、不乱飘。
客户端 CV 预处理:先量再问
在把照片发给大模型之前,浏览器端先做一遍轻量 CV(public/color.js,纯 Canvas 无依赖):用 YCbCr 经验阈值抠皮肤掩膜取中位肤色、取上部最暗一撮当发色、转成 CIELAB 拿到 L*(明度)/a*/b*(冷暖代理)与发肤明度对比 ΔL,再用极简 k-means 抽 6 个主色。
/api/coloranalysis 是纯视觉的——只发图片让 GPT-5 判季型,不喂客户端算的 Lab 参数。因为单张非受控自拍的绝对色值受光照影响极大,喂进去反而可能误导;客户端 CV 更多用在质量门和离线评测校验上。调用的 API:一个反代打通所有能力
所有 AI 调用都指向一个 OpenAI 兼容的 Base URL,三个模型角色:
CHAT_MODEL = gpt-5.4-mini // 看图 + 推理(多模态),所有"判断/文字"
IMAGE_MODEL = gpt-image-2 // 文生图(无照片时兜底)
EDIT_MODEL = gpt-image-2 // 真人换装(在用户照片上改穿搭) 看图 + 推理走标准 chat completions,content 里塞文本 + image_url(base64 data URL),并用 response_format: json_object 强制结构化输出。GPT-5 系列都是多模态的;故意不传 temperature / max_tokens,避免撞上推理模型的参数限制。模型偶尔会在 JSON 外包一层围栏、写注释或留尾逗号,所以有一个宽松解析器:先剥围栏,失败就正则抠出最外层大括号,再去注释、去尾逗号才解析——这是让 LLM 结构化输出稳定落地的必要保险。
换装/生图走 images edits(multipart)和 generations,返回 base64。gpt-image 很慢(约 100 秒/张)且偶发 5xx,所以做了指数退避重试(edits 4 次、超时 200s)。
"保脸"换装:产品成败的关键
把衣服/妆容/发色画到用户本人脸上,最大的风险是身份漂移——生成出来不像本人了。这套"保脸"设计做了几层:
1Prompt 层的硬约束
换装 prompt 里硬性列举「不要改」的清单并重复强调关键约束,保留皮肤纹理/毛孔这条尤其重要——它防止模型"顺手美颜"导致身份漂移:
【严格保留】人物的脸型、五官比例、表情、发型、发色、肤色、体型体态、
姿势与背景、以及性别;保留真实皮肤纹理、毛孔与细纹,不要磨皮、不要瘦脸、
不要换脸、不要改变人脸/身材/性别。
就是这个人本人!就是这个人本人!只换衣服,其它一切不变。 2用户知识库注入(subjectLine)
把档案里的性别/体型/肤色/发型拼成一段"画面人物固定特征"约束串,每次生图前置注入。这直接修掉了早期一个严重 bug:coloranalysis 原来不返回性别 → App 默认按"女"处理 → 男用户生成出女图。现在性别由 AI 判定并锁进 subjectLine,色带 prompt 也显式"务必男性/女性、保持性别不变"。
3只用 img2img,不做换脸
我评估过 InstantID / PuLID / ComfyUI 自建管线(本机有 RTX 4060),最终只用 prompt + gpt-image 的 edits,没上任何 face-swap 模型。上面那张氛围感大片也是在用户本人照片上 img2img注入季节氛围(一份把四季映射成场景/光线/表情/发型/调色的知识库),而不是把脸换到一张模板大片上——这样保脸更稳、也不需要付费的换脸服务。
4拆任务,别让生图干它不擅长的事
一个反复验证的洞察:别让 gpt-image 一次生成带文字的整张海报(文字糊、脸不一致、颜色不准)。正确拆法是——GPT-5 出文字和颜色(准)+ gpt-image 只出色带人像(准)+ 程序排版(准)。前面那条六色色带就是这么来的:每条都是"同一人并排穿 N 色针织衫",脸一致、颜色按序、无文字,最后前端用 html2canvas 拼版导出。
配套的工程优化
- 图片缓存:生成图按"模型+尺寸+prompt+图片哈希"存盘,重复请求秒回(24h TTL);返回相对 url 兼容子路径部署。
- 减卡顿:换装底图 PNG→JPEG 0.9(小很多、编码快、省 sessionStorage);处理 canvas 上限 1400px 省内存。
- 并行:色带 / 穿搭预览 / 变体图都是一键三张并行出,把等待压到单张耗时。
- 零依赖 + 相对路径:干净挂在 nginx 子路径下,push→Actions→
git reset --hard→restart 自动部署(部署密钥用 forced-command 绑死,泄漏也只能触发这一条部署)。
评测实验:拿公开人脸集测偏差
季型判定有个根本问题——它没有客观 ground-truth。业内跨平台判定约 30% 不一致,专家判冷暖甚至会给出相反结论。所以我不追求"准确率",而是用一个可复现的实验去测分布、一致性和方向合理性。
b*(暖度代理)和 L*(深浅代理)做方向性校验。上游并发上限=1(并发即 429),严格单并发、退避重试。
第一版结果暴露了严重偏态:四季分布 85% 判"秋",undertone 88% 判"偏暖",12 型只用到 7 类且集中在深秋/柔秋;存在"深肤→判暖/判秋"的潜在族裔偏向(东亚是唯一被合理分出冷调的群体)。不过冷暖方向本身是对的——判"偏冷"的样本实测 b* 均值 3.4、判"偏暖"的 18.0,Pearson r≈0.50;明度维度更是高度吻合。而 12 型 test-retest 一致率只有 50%(四季大类稳在 83%)。
针对性纠偏:我据此重写了色彩 prompt——强制先分冷暖/明度/纯度三轴独立判断、再合成季型,明确要求"警惕室内暖光/滤镜把脸染黄""深肤色同样可能是冷调(→深冬/冷冬),绝不能一律判暖""刻意纠偏无差别判秋的倾向",并要求输出数值化三轴字段和一个别都给同一个值的真实置信度。
第二版回归(同 34 张)验证纠偏生效:
| 指标 | v1 | v2 |
|---|---|---|
| 判"秋" | 85% | 62% |
| 判"暖" | 88% | 68% |
| 冷调样本数 | 4 | 7 |
| Black 出现冷调 | 0/4 | 1/4 |
| 冬 / 春 出口 | 1 / 1 | 6 / 5 |
| 性别检测正确 | — | 33/34 |
偏态明显缓解、冷季和春季有了出口、深肤开始能被判冷调——虽然仍略偏秋,但方向对了。整套评测脚本可复用,可以作为上线前的离线分布回归。顺带一个算法层的发现:离线实测 Lab 的 hue 角 atan2(b*, a*) 比单看 b* 更能分冷暖(cool/neutral/warm 三组 hue 均值 5.3/34.4/45.2 单调分离)——这既是更好的评测指标,也指向一个更好的算法方向。
评测需要更多真实样本,所以还做了一个明确同意制的数据管线:建档屏有一个默认关闭的 opt-in 勾选 + 隐私说明页;只有勾选才会把照片和结果匿名入库,用户能在「我的」里看到贡献数并一键撤回删除。
小结
StyleLab 想证明的事情很简单:用一个通用视觉大模型 + 一个图像编辑模型,加上一层扎实的领域知识(色彩理论)和工程约束(保脸、拆任务、评测纠偏),就能把一个"看起来需要专业顾问 + 专业修图师"的体验做成一个零依赖的小网页。
难点从来不在调 API,而在:把主观的色彩体系翻译成可注入的 prompt 约束、把生图任务拆成模型各自擅长的小块、用硬约束死死锁住用户身份、以及用一个可复现的实验诚实地量出模型的偏差再去纠偏。
⚠️ 个人探索项目,非商用;测色仅供娱乐/参考——季型判定没有客观标准答案,请把它当有趣的起点,而不是权威结论。文中的色带、试穿、氛围大片均为该系统真实生成的 AI 图片。