一位使用化名Toney Alexander的开发者,最近在Hacker News上发了一个Show HN帖子:一套用于生成肤色的自定义颜色空间,配一个网页取色器和Python示例代码。核心思路很简单——在一个半径可调的球面上随机采样出三维坐标,再用一组固定系数的线性矩阵,把这三维坐标直接映射成RGB值。作者自己把这套方法定义为“good enough”,够用就行,不是权威模型。
这个判断本身没问题。问题在于,“够用”这两个字背后,藏着一条色彩科学界早就走通、但这个项目完全没走的路。
几档色块和1677万色之间,一直空着一块
表情符号只给了大约5档肤色选项,不够用就直接甩出卡通黄;化妆品品牌能拉出50个色号的产品线;到了游戏角色创建器,幅度直接跳到RGB全部1677万种颜色,配一堆预设色块加一个通用取色器兜底。
这三种方案分别代表两个极端:太粗、太随意。中间地带一直没人认真填。作者想做的,就是找一个连续、贴近真实肤色分布、又能被工具化调用的数学模型——听起来正是这个行业缺的东西。
方法论本身也确实下了功夫:先手工标注一批RGB点,判断“这个颜色像不像真人肤色”;把标注数据画出来,是一条弯弯曲曲、类似香蕉形状的曲线;再用主成分分析(PCA)把这条曲线摆正、对齐坐标轴;最后手动调参数,让一个球面套住这团数据点,反推出线性变换公式。
色彩科学早有一套答案,只是这个项目没用
在皮肤医学测量和化妆品色度学里,处理肤色不会直接在RGB空间里打转。业内更常见的做法,是先用色度仪或分光光度计实测数据,再转换到CIELAB这个感知均匀的色彩空间——它的设计初衷就是让数值差异尽量对应人眼实际感知到的差异。在此基础上,还有一个专门的一维指标叫ITA°(Individual Typology Angle),用来量化肤色深浅;色差则用ΔE来衡量,而不是简单比较RGB三个通道的数字。
这套体系和作者自创的球面采样方法,走的完全是两条路。
判断这两条路谁对谁错,得看用在哪。作者说得很清楚,这套东西是给数字艺术、角色创建器这类场景用的简化模型,本来就不是要做医学级或化妆品级的精确测量。用色彩科学的高标准去要求一个Show HN小项目,多少有点用错尺子。
但作者自己在文中列出的“局限性”章节,只谈了白癜风、高胆红素、血流这些生理层面的变量,完全没提另一个更基础的技术盲区。
被漏掉的一个变量:光照和相机也会“调色”
Hacker News社区上对这类方法有一个常见的技术质疑:如果肤色数据是从照片里采样、或者直接在RGB空间里插值生成的,那这些数值里混进去的,可能不只是肤色本身,还有光照的颜色和强度、阴影和高光、相机的曝光与白平衡、乃至显示器色域的差异。换句话说,算法学到的可能是“不同光照和相机条件下的颜色分布”,而不是“不同人真实的肤色分布”。
这不是一个可以忽略的小问题。要真正把“肤色反射率”和“环境光照”分开,理想做法需要标定图像、标准光源、色卡,甚至更专业的皮肤光谱反射模型——这些都是作者这次没有涉及,也不太可能靠一个人的业余项目补齐的工作。
- 风险.直接在RGB空间采样,可能把相机和光照的偏差,当成了肤色本身的多样性来建模。
作者页面上还展示了一个R²的拟合结果,并链接了一个解释页面。但R²高只能说明模型在整体样本上拟合得不错,不代表样本本身有代表性,更不能证明这套色域在最浅、最深或一些罕见底色上同样准确。要真正验证,得看模型是不是分区间报告了误差、有没有交叉验证、边界肤色单独测试的结果怎么样——这些,原文一个都没给。
公式漂亮不等于覆盖到位,尤其是在分布两端。
谁该关心这件事,接下来看什么
真正可能用到这套颜色空间的,是游戏角色创建器和数字艺术工具的开发者——如果打算直接拿来当预设色域用,至少得先自己跑一遍边界肤色的验证,而不是看到一个漂亮的取色器网页就直接接入。Unicode表情符号团队和化妆品色号体系的制定者面对的是同一道选择题:分档还是连续,这个项目提供了一个思路,但还没证明自己足够可靠。
接下来值得盯的,是作者会不会公开完整的分区间误差数据、是不是有色彩科学背景的人参与评审,以及这套算法有没有真的被哪个产品采用、用户反馈如何。在那之前,它更像一个有意思的周末工程,而不是一套可以直接拿来用的行业基础设施。
