用 AI 做个人色彩分析,底层在解决一个什么样的计算机视觉问题?

5 阅读11分钟

最近在做一个微信小程序「见颜计划」,核心功能是上传一张人脸照片,AI 自动分析肤色的色彩季型,输出穿搭、发色、妆容建议。 上线之后经常被朋友问:这个东西技术上怎么做的?听起来像是个玩具,但实现起来坑多不多? 这篇文章就把这个问题拆开说清楚——从色彩理论到工程实现,讲清楚"AI测个人色彩"这件事在技术层面究竟在解什么问题,踩了哪些坑,以及为什么它比看起来难很多。

一、先定义问题:输入是什么,输出是什么 做任何 AI 产品之前,先把问题定义清楚。 输入: 一张用户自拍照(JPEG/PNG,分辨率不定,光线环境不定,有无美颜不定) 输出: 用户的色彩季型(春夏秋冬四大类,或细分八型)+ 对应的穿搭/发色/妆容建议 看起来是一个分类问题:给定一张图,输出一个类别标签。但实际上这里面藏了好几个子问题:

人脸区域定位:要分析肤色,首先得找到脸在哪里,把背景、头发、衣服排除掉 皮肤区域分割:脸部也不是全部都是皮肤,眼睛、眉毛、嘴唇、胡须区域需要排除 肤色特征提取:从有效皮肤区域提取颜色特征——这里颜色空间的选择至关重要 季型分类:把提取到的颜色特征映射到色彩季型体系

每个子问题都有各自的技术挑战,逐一说。

二、颜色空间的选择:RGB 为什么不够用 做颜色分析的第一反应可能是:直接读 RGB 值不就行了? 但 RGB 有一个根本性的问题:它不是感知均匀的颜色空间。 RGB 数值上相差相同距离的两对颜色,人眼感知到的差异可能完全不同。在 RGB 空间里做颜色距离计算,结果和人的直觉感受会有明显偏差。 个人色彩分析本质上是在模拟"人眼对颜色的感知"——测色顾问在判断肤色冷暖时,依赖的是视觉感受,不是仪器读数。所以颜色空间的选择需要尽量接近人类视觉感知。 目前肤色分析常用的颜色空间有以下几种: HSV / HSL 把颜色拆成色相(Hue)、饱和度(Saturation)、明度(Value/Lightness)三个通道。这个拆法和个人色彩分析的三个核心变量(冷暖/明暗/清浊)有天然的对应关系,在实现上直觉友好。 但 HSV 同样不是感知均匀空间,在色相维度上,人眼对不同区域的敏感度差异很大——同样是色相变化 10°,在红色区域非常明显,在绿色区域则几乎察觉不到。 Lab(CIE Lab*) 这是目前最接近感知均匀的颜色空间,ISO 标准中用于颜色差异计算(ΔE)。三个通道分别是:

L*:感知亮度(0=黑,100=白) a*:红绿轴(正值偏红,负值偏绿) b*:蓝黄轴(正值偏黄,负值偏蓝)

对于肤色冷暖判断,b* 轴的值尤其关键——b* 值偏正(偏黄)通常对应暖调肤色,b* 值偏负或接近零通常对应冷调肤色。Lab 空间在颜色距离计算上更可靠,是肤色分析任务中较好的选择。 YCbCr 原本是视频压缩领域的颜色空间,把颜色信息分离成亮度(Y)和色度(Cb、Cr)。有研究表明,不同人种的皮肤颜色在 YCbCr 空间中分布比较集中,因此在皮肤检测(判断一个像素是否是皮肤)任务中使用较多。 在实际实现中,通常不会单一使用某一个颜色空间,而是在不同子任务中选用不同空间:皮肤检测用 YCbCr,颜色特征提取用 Lab,对外展示色卡用 RGB/HSL。

三、皮肤区域分割:比想象中麻烦 颜色空间选好了,下一个问题是:从哪些像素提取颜色? 如果直接取整张脸的平均颜色,结果会被眼睛(暗色)、嘴唇(偏红)、眉毛(深色)严重污染,分析结果完全失真。需要做皮肤区域分割,只保留真正的肤色像素。 这里有两条路: 方法一:基于颜色阈值的规则过滤 在 YCbCr 空间中,人类皮肤的颜色分布有一个大致的范围(Cb 在 77-127,Cr 在 133-173),可以用这个范围做粗筛,过滤掉明显不是皮肤的像素。 优点是计算快、不需要训练数据。缺点是对深肤色和极浅肤色的覆盖不够好,在复杂光照下误检率高。 方法二:语义分割模型 用 BiSeNet、SegFormer 这类轻量级语义分割模型,对人脸图像做像素级分类,把皮肤、头发、眼睛、嘴唇等区域分别标注出来,只取皮肤标签的像素做后续分析。 精度更高,对各种肤色和光照条件适应性更好,但需要训练数据和推理计算成本。在移动端部署时需要做模型压缩(量化/剪枝),否则响应延迟会很明显。 我们在「见颜计划」里用的是第二条路,基于分割模型提取有效皮肤区域,然后在 Lab 空间做特征统计。

四、特征提取:从像素到色彩变量 有了干净的皮肤像素集合,下一步是从中提取能反映"冷暖/明暗/清浊"三个维度的特征。 冷暖特征 在 Lab 空间中,a* 和 b* 的组合值可以反映肤色的冷暖倾向。但不能直接取均值——皮肤像素中有少量噪点,且在不同光照下像素分布会有偏斜,简单均值受异常值影响大。 更稳健的做法是取中位数,或者对像素做聚类(K-means),取最大聚类的质心作为代表值,过滤掉边缘噪点的影响。 明度特征 直接用 Lab 的 L* 通道均值反映整体亮度,相对直接,但需要注意光照归一化——同一个人在强光下拍的照片和在弱光下拍的照片,L* 值可能差距很大。如果不做处理,模型会把光照条件误判为肤色特征。 一个简单的归一化方法:检测图像中接近白色的区域(如眼白),用这个区域的 L* 值作为参考基准做归一化。 清浊特征 "清浊"在色彩感知上对应的是颜色的饱和度/纯度,但不是单一像素的饱和度,而是皮肤整体颜色的"一致性"。 一个直觉上的理解:清透型皮肤,各区域的颜色比较统一;雾感型皮肤,颜色分布更分散,有更多灰调混入。可以用皮肤像素在颜色空间中的分布方差来量化这个特征——分布集中对应清透,分布分散对应浑浊。

五、季型分类:规则系统 vs 端到端模型 有了特征向量(冷暖值、明度值、清浊值),最后一步是映射到季型标签。 这里有两种做法,技术思路差异比较大: 做法一:基于色彩理论的规则系统 把色彩学中对各季型的定义(比如"春季型:暖调+高明度+高纯度")翻译成特征空间中的判断规则,直接用 if-else 做分类。 优点:可解释性强,结果可预测,调试容易。对测试集之外的样本泛化能力也比较稳定,因为规则来自于领域知识而不是数据拟合。 缺点:规则的边界值怎么定是个问题。"暖调"的阈值设在哪里?中性肤色怎么处理?这些边界很难精确量化,调参过程比较依赖主观判断。 做法二:端到端分类模型 收集大量带有季型标注的人脸图像,直接训练一个分类模型(CNN 或 ViT),让模型自己学习从图像到季型的映射。 优点:如果数据量足够,精度上限更高,能学到人工规则覆盖不到的细微模式。 缺点:数据问题是核心瓶颈。 个人色彩标注需要专业顾问操作,成本极高,公开数据集几乎不存在。自行收集标注数据的质量和一致性也很难保证——不同顾问对同一个人的判断可能不同,标注噪声会直接影响模型效果。 另一个问题是可解释性。端到端模型给出的季型结论,用户会问"为什么"。规则系统可以输出"因为你的肤色 b* 值偏正,判断为暖调",模型则很难给出让普通用户信服的解释。 我们目前的实现是混合方案:用规则系统做主要判断,在规则边界模糊的中性区间引入小模型辅助决策,同时对每个特征维度的判断结果生成可解释的文字描述。

六、工程层面的几个坑 坑一:美颜滤镜 用户上传的照片有相当大比例开了美颜——磨皮、美白、调色,每一项都会改变肤色的真实特征。磨皮会降低纹理信息,美白会提高 L* 值并降低 b* 值,严重影响冷暖和明度判断。 目前没有完美解法。做法是在输入端检测美颜程度(可以用皮肤纹理丰富度作为代理指标),对高美颜图片在结果置信度上做降权,同时在 UI 层提示用户上传素颜或淡妆照片。 坑二:光照条件 室内黄光、室外白光、蓝天反光,不同光源下同一张脸的颜色差距可以非常大。前面提到的白平衡归一化能处理一部分,但对光照方向性问题(比如单侧强光导致的阴影)效果有限。 这个问题在 C 端场景下很难根治,因为你无法控制用户的拍摄环境。目前的处理思路是:对检测到强侧光的图片,在皮肤像素采样时偏向取受光面区域,减少阴影区域的权重。 坑三:多次上传结果不一致 同一个用户在不同时间上传不同照片,可能得到不同的季型结论。这个问题在中性肤色用户中尤为明显。 从技术上说这是正常的——在特征空间的边界附近,微小的输入变化就会导致不同的输出。但从用户体验上说,这会严重损害信任感。 一个缓解方法是引入置信度输出,在结论展示时明确告知用户这个季型判断的置信区间,而不是给出一个看起来绝对确定的标签。置信度低时,可以展示两个最可能的季型及各自的概率。 坑四:小程序端的推理延迟 把模型部署到服务端做推理,网络 RTT 加上推理时间,冷启动情况下响应可能超过 5 秒。对于一个"上传照片 → 看结果"的产品流程,这个延迟体验很差。 优化路径:图像压缩在客户端做(减少上传体积);人脸检测和分割可以用轻量模型(如 MobileNetV3 backbone 的分割头)部署到端侧做预处理,服务端只接收裁剪后的皮肤区域数据;对季型分类这个低频任务,结果可以做缓存。

七、这个问题比看起来难在哪里 写到这里,可以回答最开始的问题了:AI 做个人色彩分析,难点在哪里? 不是模型不够强——CV 领域的基础技术(人脸检测、语义分割、颜色分析)都已经相当成熟。 难点在于:

  1. 标注数据稀缺。 色彩季型标注需要专业知识,且行业内标准不统一,很难构建高质量、大规模的训练集。
  2. 输入不可控。 用户上传的图片质量、光照、美颜程度差异极大,鲁棒性工程量很大。
  3. 评估标准模糊。 "这个季型判断准不准"很难有客观的 ground truth,专业顾问之间的判断本身就存在分歧。
  4. 用户预期管理。 技术上的概率输出,如何转化成用户可以信任的确定性结论,是产品层面的难题。 这些问题没有完美解法,只能在工程上做取舍和逼近。

如果你对某个具体环节感兴趣(比如分割模型的选型对比、Lab 空间的特征工程细节、小程序端侧推理的部署方案),可以在评论区说,后续可以单独写一篇展开讲。 「见颜计划」目前还在持续迭代,也欢迎感兴趣的朋友来体验,技术反馈比一般用户反馈对我们更有价值。