为何Google Android ML Kit人脸检测戴口罩仍识别嘴部Landmark?求判断方法
解决ML Kit人脸检测遮挡后仍返回关键点的问题
ML Kit的人脸关键点(Landmark)是基于人脸整体结构预测得出的,即使嘴部/眼部被口罩、墨镜遮挡,模型依然会返回预测的关键点位置,所以靠mouth == null这种判断是行不通的。要判断遮挡后对应关键点是否“实际可见”,得用ML Kit提供的**人脸遮挡概率(FaceOcclusion)**功能,步骤如下:
1. 开启遮挡检测配置
创建FaceDetectorOptions时,必须显式开启遮挡分类(默认是关闭状态):
val options = FaceDetectorOptions.Builder() .setPerformanceMode(FaceDetectorOptions.PERFORMANCE_MODE_FAST) // 根据业务需求选择性能模式 .enableFaceOcclusionClassification() // 关键:开启遮挡检测能力 .build() val detector = FaceDetection.getClient(options)
2. 检测遮挡概率并判断可见性
拿到检测到的Face对象后,通过getFaceOcclusion()获取遮挡信息,根据概率值判断对应部位的遮挡程度:
// 人脸检测回调中处理结果 detector.process(image) .addOnSuccessListener { faces -> for (face in faces) { val occlusion = face.faceOcclusion ?: continue // 自定义阈值判断遮挡(概率越接近1,遮挡程度越高) val mouthOccluded = occlusion.mouthOcclusionProbability > 0.7 val leftEyeOccluded = occlusion.leftEyeOcclusionProbability > 0.7 val rightEyeOccluded = occlusion.rightEyeOcclusionProbability > 0.7 // 业务逻辑示例:仅处理未被遮挡的关键点 if (!mouthOccluded) { val mouth = face.getLandmark(FaceLandmark.MOUTH_BOTTOM) // 处理可见的嘴部关键点 } if (!leftEyeOccluded) { val leftEye = face.getLandmark(FaceLandmark.LEFT_EYE) // 处理可见的左眼关键点 } } }
注意事项
- 遮挡概率的阈值(比如示例中的0.7)需要根据实际场景测试调整,平衡误判和漏判的情况;
- 确保使用的ML Kit人脸检测依赖版本支持遮挡分类(依赖为
com.google.mlkit:face-detection:x.x.x,建议使用较新版本); - 无论遮挡程度如何,
getLandmark()大概率会返回非null对象,所以必须以遮挡概率作为判断依据,而非关键点是否为空。
内容的提问来源于stack exchange,提问作者anylife
相关产品推荐
相关产品推荐

