☰
基于人脸关键点的收费亭微笑服务AI评测系统落地实践
2026/10/17 2:10:18 网站建设 项目流程

前阵子接了个高速公路收费服务质检的项目,客户开篇就问了一个让做视觉算法的人听了想皱眉的需求:能不能用算法盯着收费亭,判断每个收费员的微笑服务达不达标?说实话,我第一反应是,这是不是有点大材小用。等项目真的推进到现场,我才发现,让AI走进收费亭、把微笑服务变成可量化的指标,背后要处理的工程细节和"人的问题",比训练一个识别模型要复杂得多。

这个项目最后做出来了一套完整的收费亭微笑服务AI评测系统,覆盖了几十个收费站的车道。今天把整个落地过程里我认为最值得说的东西写下来,从需求定义、微笑指标的计算、现场硬件部署,到服务窗口期判断、考核打分校准,一次性讲透。无论你是做计算机视觉的同行,还是交通行业里想引入AI做服务管理的运营人员,这篇内容应该都能给你一些参考。

1. 收费亭里的微笑考核,为什么最后绕不开算法

1.1 人工抽检的困局

先交代业务背景。高速公路收费站的服务考核里有一项规定叫"微笑服务",收费员在服务司乘的整个过程中要保持自然微笑,配合唱收唱付、文明用语。看起来就是一句考核要求,但真落下去执行,问题非常多。

过去怎么查?稽查员在监控中心翻录像,从每个车道一天的视频里随机抽几个时段,人工看收费员有没有笑。有次甲方跟我们吐槽,说一个中型收费站一天有五六千辆车通过,每个收费员一个班次要服务两三百台车,稽查组一个月能抽查几百个片段就算很勤快了,覆盖率大约只有1%到2%。这带来两个直接后果:一是抽样太少,服务质量的真实波动根本没被看见;二是判定标准太主观,同一个微笑片段,甲稽查觉得"笑容自然、加分",乙稽查认为"嘴角僵硬、应付了事",同一段视频打分能差出二十分。

后来甲方内部也试过加强现场巡查,让管理员在车道外来回走,用巡逻代替视频抽检。结果更麻烦。收费员一看到管理员走近就条件反射地挂上标准笑容,人一走笑容立刻消失。这种"人来疯"式的管理,查到的只是表演,不是常态。

1.2 需求边界:识别行为规范,而不是识别心情

我们项目组第一次开需求会时,甲方给了个很宽泛的说法:"能不能让AI自动看收费员笑没笑?"

第一版我们对需求的理解是"做一个表情识别系统,判断收费员是高兴还是不高兴"。这个方向在技术上完全可以做,但仔细一琢磨就走偏了。收费员微笑服务,不是为了表达"我现在心情很好",而是在履行工作规范。所以算法要回答的问题,不是"收费员此刻情绪如何",而是"收费员在服务司乘的这个过程中,有没有按照规范做出微笑表情动作"。

这个边界区分很重要。它决定了后续所有的技术选型。

情绪识别模型关注的是面部表情与内在情绪的映射,而我们要做的是行为合规检测,更接近"动作识别+表情动作量化"。说直白点,就是判断"这个表情动作够不够得上服务规范里的微笑标准",而不是判断"这个人笑得开不开心"。边界一旦清晰,后面和甲方沟通技术方案就顺畅多了。

1.3 算法必须回答的三个问题

整个需求梳理下来,算法系统最终要回答三个问题:

  1. 某个时间段内,画面里的收费员是谁?
  2. 这个收费员在服务哪一辆车?服务窗口期是什么时候开始、什么时候结束?
  3. 在服务窗口期内,收费员面对司乘的那些帧里,微笑动作是否达到规范标准?

这三个问题分别对应人脸识别/跟踪、服务过程切分、微笑强度评估。看起来很直接,但每个问题落到现场都会拉出一堆细节。比如第二个问题,一辆ETC车从进车道到抬杆离开,全程不过十几秒,怎么判断"开始服务"和"结束服务"?第三个问题里,收费员低头找零钱、侧身拿计重单的时候,脸都没对着司机,这些帧该不该计入微笑评估?这些都是必须想清楚再动手的事。

有一点我特别想提醒做类似项目的同行:别急着上模型,先把考核场景里的业务规则摸清楚。算法只是最后执行规则的机器,规则定义错了,模型再准也是白搭。

2. 把"笑"拆成大数:68个关键点与微笑强度SM

2.1 关键点从哪里来

"微笑"在人类眼里是一个整体印象,但计算机没有整体印象,它只能看数字。我们要做的第一步,就是把"笑得怎么样"翻译成一组可计算的数字。

我当时选的技术路线是人脸关键点检测。人脸关键点就是面部关键位置的坐标点,比如左嘴角、右嘴角、上唇中心、下唇中心、鼻尖、左右眼角等。常见的有68点、106点、240点等不同密度。考虑到收费亭内边缘设备算力有限,我们选了在移动端优化较好的轻量级人脸关键点方案,在画面上检测出人脸后,输出68个关键点坐标。

这套方案的好处有两个:一是结构化,关键点坐标直接描述嘴部、眼部的几何形状,不需要像深度特征那样"黑盒解释";二是轻量,单帧处理十几毫秒就能完成,满足实时性。对甲方来说,后续如果被质疑某个判断不合理,可以拿出具体证据:"这一帧嘴角上扬角度是8度,嘴部张开度0.3,所以我们判定为微笑",有据可查。这种可解释性在考核场景里非常重要。

2.2 微笑强度SM怎么算

关键点有了,接下来要定义微笑强度。我把"微笑"拆成三个肉眼可见的物理特征:

  • 嘴角上扬角度:微笑时嘴角轮廓整体向上提,左右嘴角连线与水平线的夹角会产生正增量。
  • 嘴部张开程度:自然微笑时嘴巴会轻微张开,上下唇之间出现距离。
  • 脸颊隆起位移:微笑时脸颊肌肉向上挤压,脸部两侧的关键点位置会相对中立状态发生位移。

每一帧图像,我们基于68个关键点坐标算这三个特征值。下面是当时计算微笑强度SM(Smile Magnitude)的核心逻辑:

import math # 假设landmarks为68个人脸关键点坐标,索引按dlib/通用68点规范 # 左嘴角48、右嘴角54、上唇中心点51、下唇中心点57 left_mouth = landmarks[48] right_mouth = landmarks[54] upper_lip = landmarks[51] lower_lip = landmarks[57] # 1. 嘴角上扬角度:左右嘴角连线相对水平线的角度 angle = math.atan2(right_mouth.y - left_mouth.y, right_mouth.x - left_mouth.x) angle_norm = max(0.0, min(1.0, (angle - (-0.1)) / (0.2 - (-0.1)))) # 2. 嘴部张开度:上下唇中心点距离 / 两外眼角距离(归一化) mouth_open = dist(upper_lip, lower_lip) / dist(landmarks[36], landmarks[45]) # 3. 脸颊位移:左右脸颊关键点相对基准帧的垂直位移均值 cheek_shift = (abs(landmarks[2].y - cheek_baseline_left) + abs(landmarks[14].y - cheek_baseline_right)) / 2.0 # 综合微笑强度:权重来自标注数据回归 sm = 0.3 * angle_norm + 0.4 * mouth_open_norm + 0.3 * cheek_norm

这里面的权重不是拍脑袋定的。我们采集了两百多段真实收费亭服务视频,切片后让六名标注员独立给每一帧的"微笑可见度"打分,从0到5分。再拿三个特征值和标注分数做线性回归,拟合出合适的权重系数和归一化区间。最终SM落在0到1之间,数值越高,微笑动作越明显。经过和人工标注的比对,SM在0.55以上时,大多数人都会认为"确实在微笑"。所以我们把0.55定成了微笑帧的判定阈值。

2.3 为什么不用现成的情绪识别模型

项目评审时有人问过:网上开源的开心/难过分类模型不是现成的吗?直接拿来用不行吗?这里我多说几句。

通用情绪识别模型大多是在实验室数据集上训练的,输出的是七个情绪类别,比如开心、悲伤、惊讶、愤怒。它对"笑脸"的判断往往是一个二分类结果:这是笑脸或者不是笑脸。但我们这个场景恰恰不只需要"是不是笑",还需要"笑得够不够到位"。服务考核要的是连续幅度和持续时间,不是零和一。另外,通用模型一进监控场景效果立刻打折,因为训练数据多是正脸高清照片,而真实场景里有逆光、侧脸、遮挡、低分辨率,模型置信度会乱跳。

更关键的是可解释性。收费员如果被算法判了"微笑不达标",人家肯定要问凭什么。通用情绪识别模型只能给出一个黑盒深度的预测结果,连开发人员都很难讲清楚是哪个特征导致了判断。而关键点方案能把"嘴角上扬几度、嘴巴张开多少"作为证据摆出来,员工服气,管理人员也好做绩效沟通。这里我个人的经验是:凡是涉及对人的考核评价,能不用黑盒模型就不要用,哪怕准确率稍微低一点点,可解释性带来的落地优势也远远大于那点精度提升。

3. 走进现场才发现三个"看不见的敌人"

3.1 摄像头装在哪:三轮改动后的最终方案

模型在办公室测试集上跑得很好,一到现场全露馅。第一个问题就是摄像头部署。

第一版方案参考常见监控布局,把摄像头装在收费亭室内正中,正对收费员的正面。装完一看画面:收费员座位离摄像机两米多,人脸在画面里只占巴掌大小,关键点检测大面积失效。更要命的是,收费员在亭内活动范围不小,服务时经常向右转身面向司机,脸一偏,正面机位拍到的就剩下半张侧脸。

第二轮我们改成了桌面近景机位,把摄像头立在收费员操作台侧面,距离人脸约60到80厘米,这样人脸的像素宽度能做上去。但新问题来了:操作台侧面会挡住部分收费员的视线,而且收费员伸手接卡的动作经常把摄像机整个挡住。

三轮方案最后定型,是在收费亭窗沿上方装一个带可调角度支架的工业摄像头,镜头下倾约15度,和人脸水平面形成一个自然的俯拍角度,距离约80厘米,焦距6mm。这样画面里人脸宽度能稳定在80到120像素,同时不遮挡收费员操作。关键点检测对正脸最敏感,这个俯角也在检测网络能接受的范围。多说一句,测试时一定要用亭内实际的光线条件多录几段,不同时段的光照对关键点检测影响非常大。

3.2 口罩与帽子:当嘴部不可见时

项目运行期间有一段时间,收费站要求全员佩戴口罩。人脸检测模型能找到人脸框,但68个关键点落到口罩区域时,嘴巴部分的坐标完全是外推出来的,置信度低到没法用。嘴部特征全部失效,单靠脸颊位移也撑不起来,整个微笑检测基本瘫了。

我们的应对思路是切到"眼部微笑识别"模式。心理学里有一个概念叫杜兴微笑,真笑的时候,除了嘴角上扬,眼轮匝肌也会收缩,表现为下眼睑微微上抬、外眼角周围出现细纹。我们改用眼睛区域的关键点来计算眼部开合度和外眼角梯度强度,用这两个量代替嘴部特征。具体做法是:计算左右眼的EAR值(眼睑纵横比),真实微笑时眼裂会明显变窄,EAR数值下降;同时计算外眼角局部区域的梯度强度,捕捉鱼尾纹的生成。

切换之后,检测率恢复到七成左右,但精度确实比嘴部特征低。所以我们提高了口罩模式下的微笑判定阈值,并且把这类"眼部关联微笑"的片段标记为"待人工复核优先级较高",不直接一刀切纳入考核。

3.3 逆光、反光与白平衡

收费亭最大的环境坑是窗玻璃。摄像头的物理位置在亭内,镜头难免会拍到收费员身后的窗户,白天外部阳光一照,玻璃反光经常把脸部的对比度压得极低,人脸暗成一团。晚上车灯扫过来,有时还会短暂过曝。

我们做了三件事。第一,把摄像头安装位置从玻璃正面的直射路径上挪开,同时加一个简单的遮光罩,用物理手段削弱直接反光。第二,开启摄像头的宽动态(WDR)模式,出图时再做一次自适应直方图均衡,把暗部细节拉出来。第三,手动固定白平衡,避免夜间路灯、车灯这种色温多变的场景让肤色发生漂移,因为肤色漂移会影响关键点网络的置信度。

这一套组合下来,有效识别帧率从最初的76%提到了93%。剩下的7%主要是极端强逆光或者严重遮挡,我们的处理原则是不硬判,标记为"数据不足",交给人工复核。

4. 关键不是"笑没笑",而是"服务窗口期内笑没笑"

4.1 把一次收费服务切成状态机

最早我们犯过一个"技术洁癖"式的错误:拿着连续视频流逐帧分析脸部表情,只要某一帧检测到收费员在笑,就认为这一单服务微笑合格。跑了一周数据发现,全站合格率惊人地高,再一看结果,逻辑上出了大问题——收费员在亭里坐着,等车的时候跟同事聊天笑,或者低头看手机傻笑,这些帧也被算进去了,根本不算服务过程中的微笑。

于是我们把一次收费服务定义成一个状态机,用外部信号而不是视觉信号来标记服务起止:

  • 空闲状态:车道无车,不采集任何服务数据。
  • 车辆进入:车道下方感应线圈触发,或车牌识别系统上报"来车",状态切到"服务中"。
  • 服务结束:抬杆信号触发,且车辆驶离感应区域,状态切回"空闲"。

只有"服务中"这个状态下的视频帧,才进入微笑检测流程。这个改动是整套系统逻辑里最关键的一次校正。算法要判断的不是"这十分钟里你有没有笑过",而是"你服务这辆车的时候有没有保持微笑"。

4.2 朝向判断:哪些帧算"面向司机"

服务窗口期内的视频帧也不是全都有用。收费员在这个过程里要完成一系列动作:迎接车辆时面向司机、确认车型时低头看屏幕、取卡时侧身、递票时面向司机、找零时低头数钱。如果我们把低头数钱那几帧的表情也算进微笑评价里,算法就会一直报"不合格",因为低头时嘴角状态根本检测不到。

所以我们在微笑检测前加了一层头部姿态估计,计算头部在三个方向上的旋转角yaw、pitch、roll,只有同时满足yaw角度小于25度、pitch角度小于15度的帧,才被认定为"面向司机的有效帧"。这些有效帧里再计算微笑强度。低头数钱、侧身拿卡、转头看屏幕的帧会被过滤掉,不进考核数据。这样既保证了考核的公平性,也把误判率压了下来。

4.3 单笔业务怎么打合格或不合格

有了有效帧和微笑强度,单笔服务的评价逻辑就清楚了。我们设定了一套三层规则:

  1. 单笔服务窗口时长不小于5秒才参与评价,太短的车(比如前车故障、即停即走)不评,退回人工处理。
  2. 计算微笑帧占比:有效帧中SM大于0.55的帧占比。
  3. 单笔服务合格线是微笑帧占比不低于60%;超过80%且平均微笑强度超过0.65,判为优秀;低于60%则判为不达标。

举个例子,收费员处理一笔现金缴费业务,服务窗口15秒,每秒抽5帧,共75帧有效帧。其中"面向司机"的帧有60帧,这60帧里有42帧微笑强度达标,占比70%,这笔业务就是合格。如果这位收费员全程板着脸,有效帧90帧里只有18帧嘴角有上扬,占比20%,系统直接判不达标。

这套评价口径是跟甲方运营部门反复对齐过才定下的。他们最初的期望是"只要笑了就算合格",我们建议"必须在面向司机的有效帧里达到一定比例才算合格",最终甲方接受了后者。现在回看,这个是让系统真正能落地的一个关键决定。

5. 实测中排掉的三个"看起来不算Bug"的Bug

5.1 ETC车一进一出,一次服务被重复计数

系统在测试站跑了两个星期,我们检查日报时发现一个奇怪现象:ETC车道的服务数量远大于实际交通流量,某些车牌一天的服务次数高得离谱。

排查链路从输出倒推。先看原始记录,发现一辆ETC车在90秒内被系统划分成了三段服务,而现场实际情况是车辆在缴费后栏杆抬起慢,车在车道内缓缓蠕动,中间还因为前车排队停了几秒。我们的状态机把一次物理服务切成了多个逻辑服务,导致同一笔服务被重复评价,且每段都不足5秒,大量进入"无法评估"人工复核队列,把人工复核量直接抬高了四倍。

修复方案是给状态机增加冷却时间机制:一次服务结束后,60秒内不允许开启新的服务状态;同时以车牌识别结果为主键,同一车牌在同一车道的服务记录合并成一个会话。MOT视觉跟踪在这个场景里反而不是最可靠的主解,因为车道拥堵时前车后车挤在一起,跟踪ID很容易互换。

5.2 低头、侧身、歪头:长尾姿态带来的假阳性

第二阶段测试里出现了另一类问题:明明是低头缴费的侧脸帧,算法却报成了"微笑正在发生"。我翻出误报截图仔细看,原因很清晰——收费员低头时下颌线的弧度被关键点网络当成了嘴角上扬线,嘴部特征值出现了一个假峰值。

这个坑属于典型的"模型外推误差"。我们的姿态过滤确实挡掉了一部分大角度歪头,但阈值的边界附近仍然有漏网之鱼。最终处理是双管齐下:第一,把姿态估计的前置条件从"过滤后统计"改成"过滤后再检测",凡是yaw或pitch超quote角的帧,不参与关键点检测,直接从源头上掐掉;第二,提高关键点检测的置信度阈值,从0.7提到0.8。宁可少报一些微笑,也不乱扣分。调整后假阳性率从8.7%降到2.1%。

5.3 "嘴在笑,眼不笑":被算法放过的职业假笑

系统上线一个月后,运营方跟我们反馈了一个很有意思的现象:有些收费员发现算法看嘴部特征,开始练"嘴角上扬"的肌肉记忆,嘴上扬起标准弧度,但眼睛没有任何笑意。人工看录像怎么看怎么别扭,可算法却给了满分。

这就是经典的假笑问题。解决办法是引入眼轮匝肌活跃度判断,也就是前面口罩方案里用到的眼部特征。具体逻辑调整为:一帧只有同时满足嘴部SM达标和眼部活跃度达标,才记为"真微笑帧";光嘴角动、眼睛没反应,标记为"疑似机械微笑"等级,不纳入微笑帧占比。

这个调整以后,有个收费员私下跟我说,以前对着镜子练嘴角弧度就够了,现在得真的发自内心笑一笑,不然眼睛那关过不去。这话虽然是玩笑,但恰好说明指标设计在引导真实行为改变。

5.4 怎么防模型自己退化

只要系统在跑,"模型静默退化"就会存在。起初我们整个项目组也没把这件事放在重点位,直到有一天日报显示全站微笑达标率骤降20%。

我们当时第一个反应是站点服务质量出了问题,准备打电话跟站长沟通。结果多看了一眼数据分布,发现所有收费亭、所有车道、所有班次全部同步下跌,这就不是人的问题——再集体性的服务质量滑坡也不可能全站同时发生。查了当天硬件状态,发现是因为连续阴雨天,亭内光线整体偏暗,摄像头自动增益把画面噪点放大了,关键点检测稳定性下降,SM普遍低估。

从那以后我们建立了一套日监测机制:每天统计各车道的SM分布、微笑帧占比、关键点置信度均值,一旦全站指标出现超过15%的同步波动,就会触发模型校准流程,而不是直接怀疑收费员偷懒。这个"先怀疑系统,再怀疑人"的排查顺序,做AI质检项目一定要刻在脑子里。

6. 算法分数要变成考核分数,中间还有两道手续

6.1 人工分与算法分的回归标定

算法输出的达标、不达标、优秀三级评价,要直接写进收费员的绩效表,必须跟原有的考核体系对接。原来的考核表里,微笑服务占总分100分里的20分。我们采用的方式不是让算法直接打20分,而是让算法先算出一个基础服务得分,再用人工复核结果做校准。

单笔服务得分公式设为:S = 12 + 8 × (0.6 × 平均微笑强度 + 0.4 × 微笑帧占比)。举个例子,某收费员一笔业务平均微笑强度0.7、微笑帧占比0.9,这笔业务的得分就是12 + 8 × (0.42 + 0.36) = 18.24分。

为了让这个公式和人工评价对齐,我们做了300段真实服务片段的回归标定,六名业务专家先独立打分,再和我们公式计算的分数做相关性分析,最终线性相关系数控制在0.8以上,甲方认可后这个公式才进入正式考核流程。这一步看起来是数据分析工作,但实际决定了系统能不能被业务方接受——考核规则一旦出现"算法说A、专家说B"的对立,整个系统的公信力就垮了。

6.2 假阳性与假阴性:输出"不确定"也是一种处理

实测过程中,算法误差不可避免,关键是想清楚怎么处理误差。常见两类情况:

第一类是假阳性,算法判定合格,人工复核时看着不舒服。典型场景就是前面说的职业假笑。虽然我们加了眼部判断,但仍然存在边界情况。我们的处理方式是给这类样本打上"疑似机械微笑"标签,不直接判不合格,而是推送给管理端人工复核,由站长或稽查员二次确认。

第二类是假阴性,算法判不达标,人工看视频发现收费员确实也在笑,只是角度偏、遮挡,算法没敢认。针对这种情况,我们规定凡是有效帧少于15帧的服务会话,算法不输出"不达标",只输出"数据不足,需人工复核",同时把原始脱敏视频片段附在后面。

加了一个"无法评估"分类后,系统的整体争议率大幅下降。这个经验分享给做场景化AI落地的同学:三分类的"不确定",永远好过二分类的"硬判"。

6.3 申诉入口与数据留存:给一线员工留退路

最后一点是制度设计,不是技术问题,但对系统能否平稳运行影响极大。

确定考核口径时,我们坚持加了两条规则:一是收费员对当天考核结果有异议时,可以在后台系统发起申诉,申诉后提取该服务会话的脱敏录像特征和关键点数据,转到人工复核队列,由值班站长做最终裁决;二是所有用于考核的原始视频流只保存90天,存储层做脸部区域的脱敏处理,核查结束后自动清理。

这个"申诉入口"刚开始被甲方认为是多此一举,但实际运行后发现,它极大缓解了一线员工的对抗情绪。收费员每天看到自己某笔业务被判不达标,第一反应不是反思,而是"我不服"。有了申诉路径,情绪就有了出口。一个技术项目落到人的管理场景里,光追求算法精度是不够的,还得给制度留出呼吸空间。


项目收尾的时候,我回看最初那个"能不能用算法看收费员笑没笑"的需求,觉得最后交付的其实不只是一套算法系统,而是一整套把"微笑服务"从主观印象变成客观数据流程的机制。算法给每个人都做了一把统一的尺子,但这把尺子不能抖,得让人看得懂、够得着、有地方说理。

我最大的体会是:AI进收费亭,最难的不是让机器学会看懂微笑,而是让被看的人接受机器是一个"不带偏见的监督者"。我们项目组最后很欣慰的一点是,这套系统成了收费员愿意开的玩意儿——他们每天上班第一件事是瞥一眼屏幕上的达标率变化,慢慢有人在窗口比谁的笑更自然了。算法当然不会心情不好,也不偏袒谁,这是它比人强的地方。但真正让系统跑下去的,永远是背后那些愿意接受它、甚至愿意跟它较劲的一线员工。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询