人脸聚类:从一张脸到一个人物,我怎么判断是不是同一个人
上一篇写了:自然语言搜索:我怎样把预期做进引导里。
自然语言搜索,方便用户凭自己对图片、视频的记忆——时间、地点、画面特征——快速把内容找出来。而对于相册这种应用,用户往往还会有另一个期待:集中浏览某个人的照片和视频。
笑笑相册侧边导航栏有一项叫「人物」。打开后是一排排「人」:每人一张脸作头像,名字一开始默认是「未命名」,点进去就是这个人相关的照片、视频墙。要把库里反复出现的脸收成这样,关键就一句话:这两张脸,算不算同一个人?这篇写的,就是我怎么定这条判断线。
先说清:从一张脸到一个人,中间在判什么
图和视频进库后,本地先找出画面里的脸;找得出、又没有糊到没法比的,才拿去两两比「像不像」。比完之后,像同一个人的脸归到一起,在「人物」里就多出一个可点开的人——新聚出来的默认没名字,点进去看到的是含这张脸的整张照片/视频。
所以「从一张脸到一个人物」,程序真正在做的判断只有两层:
- 这张脸有没有资格参与同人判断
- 参与之后,算不算同一个人
下面分开说 ——
第一层:谁有资格被拿来判
不是画面里闪过的每张脸都会进入同人判断。找不出脸的(背影就常常如此),或脸太糊太弱、没法可靠往下比的,直接不进这一步。照片、视频仍在库里,时间线、搜索照样能找——只是不拿它们去做「是不是同一个人」的判断。
这一层的用意很直接:脸都认不清,硬拿去比,只会多出误并。
第二层:像不像时,我怎么定调
理想状态当然是:同一个人在「人物」里只出现一次,点进去就能看全。现实里很难一步到位——同一个人跨越光线、年龄、角度、妆造之后,脸看起来差很多,「像不像」就不容易一次判准。
程序若为了凑成「一个人一个入口」而放宽判断标准,最常见的代价就是误并。两条路的优劣其实很清楚:
- 偏合并:列表更短、更省事;一旦乱并,尤其是路人脸混进人物相册里最常打开的那几个人,清理成本高,体验也伤得重。
- 偏拆开:同一人可能暂时占两三个甚至更多入口,要自己点一次合并;但拿不准时先拆开,误并会少很多。
做的过程中我反复测、反复改,判断用的阈值参数也调过很多轮,最后定下来的取向是:宁可拆碎,不可乱并。拿不准时,程序默认拆开,把「并」留给人。
这里要单独说一句宝宝脸。宝宝五官辨识度低,不同宝宝之间、宝宝和部分成人脸之间,都更容易「看起来差不多」;同一宝宝从几个月大到两三岁,脸变化又很快,同人拆成多个入口更常见。所以即便选了偏拆开,宝宝相关的误并、多拆也仍会碰到——它本来就是同人判断里更难的一块,不是参数调一调就能消失的。对笑笑相册这种偏家庭相册场景的,「人物」里宝宝往往又是最常打开的那个,乱并带来的后续清理代价更高,更不应为了「一人一入口」去放宽程序的判断标准。
判断之后:人怎么接住程序的结果
程序判完,不会强推「建议把这两人合并」。用户可以把拆开的几个人合并成一个,也可以把归错的脸挪到别人名下,也可以将默认人物封面更换成自己喜欢的头像封面。
这不是事后补丁,而是同人判断设计的一部分:程序负责在不确定时保守聚类;人负责在看得清的时候把该并的并到一起。人一多时,「仅出现 1 次」且还是未命名的可以收起来,那是列表噪声问题,已经不是「算不算同一个人」本身了。
说到底,这是程序判断同人时的设计取向:不怕暂时拆开,就怕并错。拿不准时先拆成好几个人,用户自己合并就行;一旦把不相关的脸并进常看的人,清理起来又慢又糟心。在我看来,这条线守住了,「人物」才值得放在侧栏里。