基于开源模型搭建实时人脸识别系统(四):人脸质量

news2024/9/23 13:26:28

续人脸识别实战之基于开源模型搭建实时人脸识别系统(三):人脸关键点、对齐模型概览与模型选型_CodingInCV的博客-CSDN博客
不论对于静态的人脸识别还是动态的人脸识别,我们都会面临一个问题,就是输入的人脸图像的质量可能会很差,比如人脸角度很大,人脸很模糊,人脸亮度很亮或很暗。这些质量低的图像不仅造成识别失败,还可能引起误识别。因此,对输入人脸识别进行一定的质量过滤是很必要的。这个领域的英文为Face Image Quality Assessment。
image.png

image.png

传统方法

传统的方法一般是将图像质量领域(Image Quality Assessment)的方法应用到人脸图像上,比如使用边缘检测来评测模糊、统计平均像素值来评测亮度。这些方法没有特别考虑人脸图像的特点,效果一般。

深度学习方法

普通深度学习方法

这类方法将人脸图像质量作为一个普通的深度学习问题,通过人工或预设算法对数据打标,然后设计一个网络,回归质量分数。这个方法的学习目标主要还是人眼感知上的质量,因为标签来源于人工打标,而并不是对于识别效果更好的质量。
这类方法的主要难题在于数据标签难获得,网络结构上只是简单的回归网络。

面向人脸识别的人脸质量评估

人脸质量的筛选目标是提高人脸识别的效果,因此越来越多的方法开始将人脸质量和人脸识别任务结合起来,结合的方式主要有2种:
一种是直接训一个特征能够用来衡量人脸质量的模型,代表是MagFace, 基本思想是用特征的模长来表征人脸质量。个人觉得这种方式实用起来存在一个问题就是要获得人脸质量就得进行人脸特征提取,开销太大。
另一种方式是通过人脸识别模型的特征关系来生成质量标签,代表方法:
SER-FIQ: 同一个人脸多次推理(开启dropout),统计多次推理特征的距离,对于质量好的图片,特征平均距离小,反之越大
SDD-FIQ: 统计计算人脸与同一ID和不同ID人脸的距离
FaceQnet, PCNet等

方法选择

理论上,面向人脸识别的人脸质量评估效果更好,不过这些方法与识别模型存在较大的耦合关系,根据笔者在私有数据上的实际测试,训练比较困难,开源出来的预训练模型也较大。KaenChan/lightqnet: Deployment of the Lightweight Face Image Quality Assessment (github.com) 这个比较轻量,但实测对于人脸区域比较敏感,没有区分度。
综合速度要求,选择 KS‐FQA: Keyframe selection based on face quality assessment for efficient face recognition in video - Bahroun - 2021 - IET Image Processing - Wiley Online Library
这个方法考虑了人脸角度、亮度、大小、模糊。速度较快,也有一定区分度,不过也还是有些缺陷,对于大侧脸的过滤效果一般。

import numpy as np
import cv2


class FaceQualityOverall:
    def __init__(self, **kwargs) -> None:
        pass

    def pose_score(self, face_box: np.ndarray, landmarks: np.ndarray):
        center_x, center_y = (face_box[0] + face_box[2]) / 2, (face_box[1] + face_box[3]) / 2
        nose_x, nose_y = landmarks[2][0], landmarks[2][1]
        distance = np.sqrt((center_x - nose_x) ** 2 + (center_y - nose_y) ** 2)
        face_size = np.sqrt((face_box[2] - face_box[0]) ** 2 + (face_box[3] - face_box[1]) ** 2)
        pose_score = max(0, 1 - distance / face_size)
        return pose_score

    def sharpness_and_brightness_score(self, image: np.ndarray, face_box: np.ndarray):
        box = face_box[:]
        box = box.astype(np.int32)
        face_image = image[box[1] : box[3], box[0] : box[2], :]
        face_image_gray = cv2.cvtColor(face_image, cv2.COLOR_BGR2GRAY)
        # blur the face image with a 5x5 guassian kernel
        blur_face_image = cv2.GaussianBlur(face_image_gray, (5, 5), sigmaX=1, sigmaY=1)
        # calculate the sharpness score
        sharpness_score = np.sum(np.abs(face_image_gray - blur_face_image)) / np.prod(face_image_gray.shape)
        sharpness_score = sharpness_score / 255.0
        sharpness_score = min(1, sharpness_score * 2)
        brightness_score = np.mean(face_image_gray)

        # normalize the brightness score
        if brightness_score < 20 or brightness_score > 230:
            brightness_score = 0
        else:
            brightness_score = 1 - abs(brightness_score - 127.5) / 127.5

        return sharpness_score, brightness_score

    def resolution_score(self, face_box: np.ndarray):
        face_width = face_box[2] - face_box[0]
        face_height = face_box[3] - face_box[1]
        resolution_score = min(1, min(face_width, face_height) / 224)
        if face_height/face_width > 2.5:
            resolution_score = 0
        
        if min(face_width, face_height) < 48:
            resolution_score = 0

        return resolution_score

    def run(self, image: np.ndarray, face_box: np.ndarray, landmarks: np.ndarray):
        pose_score = self.pose_score(face_box, landmarks)
        if pose_score < 0.3:
            return 0
        sharpness_score, brightness_score = self.sharpness_and_brightness_score(image, face_box)
        if sharpness_score<0.1:
            return 0
        resolution_score = self.resolution_score(face_box)
        if resolution_score < 48/224:
            return 0

        output = np.array([pose_score, sharpness_score, brightness_score, resolution_score])
        weight = np.array([0.3, 0.4, 0.1, 0.2])
        return np.sum(output * weight)


if __name__ == "__main__":
    from face_recognition_modules.face_alignment.face_landmarks import FaceLandmarks
    from face_recognition_modules.face_detection.yolov8_face import Yolov8Face
    import cv2

    yolo8face = Yolov8Face(model_path="models/yolov8-lite-t.onnx", device="gpu")
    landmarks_det = FaceLandmarks(model_path="models/student_128.onnx", device="gpu")
    image = cv2.imread("test_images/1.jpg")
    if image is None:
        raise Exception("read image failed")
    face_box, _ = yolo8face.run(image)
    landmarks = landmarks_det.run(image, face_box[0])
    face_quality = FaceQualityOverall()
    quality = face_quality.run(image, face_box[0], landmarks)
    print(quality)

结语

这篇我们简要介绍了一下人脸质量评估,不过笔者在这方面涉猎也不深,只是做个简单的总结,需要深入做还是有不少工作。

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/908580.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

用于优化开关性能的集成异质结二极管的4H-SiC沟道MOSFET

标题&#xff1a;4H-SiC Trench MOSFET with Integrated Heterojunction Diode for Optimizing Switching Performance 摘要 本研究提出了一种新型的4H-SiC沟道MOSFET&#xff0c;其在栅槽底部集成了异质结二极管&#xff08;HJD-TMOS&#xff09;&#xff0c;并通过TCAD模拟进…

Eduma主题 - 线上教育WordPress主题/网站

Eduma主题 – 线上教育WordPress主题是为教育网站、LMS、培训中心、课程中心、学院、大学、学校、幼儿园而制作的。基于我们使用以前的主题eLearning WP构建WordPress LMS的经验&#xff0c;Education WP是下一代&#xff0c;也是围绕WordPress最好的教育主题之一&#xff0c;它…

qemu - 运行树莓派

文章目录 安装 qemu下载树莓派内核使用 qemu 启动树莓派 查看 Mac 配置 uname -a我是 x86 架构&#xff0c;返回如下&#xff1a; $ uname -a Darwin S-iMac.local 22.5.0 Darwin Kernel Version 22.5.0: Mon Apr 24 20:51:50 PDT 2023; root:xnu-8796.121.2~5/RELEASE_X86_6…

基于Java SpringBoot+vue+html 的地方美食系统(2.0版本)

博主介绍&#xff1a;✌程序员徐师兄、7年大厂程序员经历。全网粉丝30W,csdn、博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ 文章目录 1 简介2 技术栈3 系统流程的分析3.1 用户管理的流程3.2个人中心管理流程3.3登录流程 4系统设计…

网络面试题(172.22.141.231/26,该IP位于哪个网段? 该网段拥有多少可用IP地址?广播地址是多少?)

此题面试中常被问到&#xff0c;一定要会172.22.141.231/26&#xff0c;该IP位于哪个网段&#xff1f; 该网段拥有多少可用IP地址&#xff1f;广播地址是多少&#xff1f; 解题思路&#xff1a; 网络地址&#xff1a;172.22.141.192 10101100.00010110.10001101.11000000 广播…

【react框架】如何手写一个超级mini的React,学完后对框架的理解也会更进一步

文章目录 前言起步工作先看虚拟dom长啥样写个createElement写个render第一次试验了解Fiber写个Fiber化函数改造render未完待续... 前言 本篇文章只是对https://qcsite.gatsbyjs.io/build-your-own-react/网站内容&#xff0c;做的一个内容的压缩&#xff0c;结合上自己的理解与…

iPhone卫星通信SOS功能如何在灾难中拯救生命

iPhone上的卫星紧急求救信号功能在从毛伊岛野火中拯救一家人方面发挥了至关重要的作用。这是越来越多的事件的一部分&#xff0c;在这些事件中&#xff0c;iPhone正在帮助人们摆脱危及生命的情况。 卫星提供商国际通信卫星组织负责移动的高级副总裁Mark Rasmussen在接受Lifewir…

基于springboot+vue的论坛系统(前后端分离)

博主主页&#xff1a;猫头鹰源码 博主简介&#xff1a;Java领域优质创作者、CSDN博客专家、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战 主要内容&#xff1a;毕业设计(Javaweb项目|小程序等)、简历模板、学习资料、面试题库、技术咨询 文末联系获取 项目介绍…

EdgeOneToMinIO

省流 使用MinIO作为EdgeOne的源站。 背景介绍 项目中需要一个兼容S3协议的对象存储服务&#xff0c;腾讯云的COS虽然也兼容S3协议&#xff0c;但是也只是支持简单的上传下载&#xff0c;对于上传的时候同时打标签这种需求&#xff0c;就不兼容S3了。所以决定自建一个对象存储…

[技术杂谈]macOS上todesk无法远程操作鼠标键盘

远程到被控Mac后能看到画面&#xff0c;鼠标键盘操作无反应 远程后发现画面显示正常&#xff0c;但是键盘和鼠标的操作没有响应 可能是辅助功能没有勾选ToDesk_Session的权限。 可按以下步骤操作&#xff1a; 1> 在左上角点击苹果图标&#xff0c;选择“系统偏好设置” …

Spring练习-29(角色添加操作)

1、点击新建 2、添加角色名称和信息之后&#xff0c;添加到数据库当中&#xff0c;与此同时你的页面要跳回 3、跳回角色列表页面 4、那是入口&#xff0c;入口就是保存 5、当你保存到表单里就是提交呀&#xff01; 6、流程是我把数据封装给某个方法&#xff1a;------》封装给一…

【Leetcode】108. 将有序数组转换为二叉搜索树

一、题目 1、题目描述 给你一个整数数组 nums ,其中元素已经按 升序 排列,请你将其转换为一棵 高度平衡 二叉搜索树。 高度平衡 二叉树是一棵满足「每个节点的左右两个子树的高度差的绝对值不超过 1 」的二叉树。 示例1: 输入:nums = [-10,-3,0,5,9] 输出:[0,-3,9,-1…

C++实现字符串的逆置

目录 C和C的区别 【1】C对C的扩充 【2】C对C的兼容 第一个C程序 【1】hello world 【2】cout标准输出流对象 i&#xff09;介绍 ii&#xff09;运算 iii&#xff09;cout的使用 iv&#xff09;使用cout指定格式的输出 练习&#xff1a;1、输出斐波那契的前10项。 【3】…

Vuex从入门到精通

文章目录 前言概念使用场景 搭建vue环境创建文件传入配置项 基本使用初始化数据getters的使用map方法使用 模块化&#xff0c;命名空间目的开启命名空间组件中读取state数据组件中读取getters数据开启命名空间后&#xff0c;组件中调用dispatch开启命名空间后&#xff0c;组件中…

聊聊磁悬浮技术

目录 1.磁悬浮的概念 2.磁悬浮的原理 3.磁悬浮的应用领域 4.磁悬浮技术的发展趋势 1.磁悬浮的概念 磁悬浮&#xff08;Magnetic Levitation&#xff09;&#xff0c;简称磁浮&#xff0c;是一种利用磁场力使物体悬浮在空中的技术。它通过在物体上加上一个磁场&#xff0c;与…

三、SQL注入之报错注入

文章目录 1、 xpath语法&#xff08;1&#xff09;extractvalue&#xff08;2&#xff09;updatexml 2、concatrand()group by()导致主键重复 报错注入就是利用了数据库的某些机制&#xff0c;人为地制造错误条件&#xff0c;使得查询结果能够出现在错误信息中。这里主要介绍报…

SOLIDWORKS基准面介绍

SOLIDWORKS是一款广泛应用于机械设计领域的三维建模软件&#xff0c;其中基准面是在建模过程中必不可少的要素。本文将介绍什么是SOLIDWORKS基准面&#xff0c;以及它在设计中的作用。 SOLIDWORKS基准面是指在设计过程中用来确定草图绘制、特征创建的参考平面。 SOLIDWORKS基…

如何在 Ubuntu 中安装最新的 Python 版本

动动发财的小手&#xff0c;点个赞吧&#xff01; Python 是增长最快的主要通用编程语言。其原因有很多&#xff0c;例如其可读性和灵活性、易于学习和使用、可靠性和效率。 目前使用的 Python 有两个主要版本 – 2 和 3&#xff08;Python 的现在和未来&#xff09;&#xff1…

一篇搞懂TCP、HTTP、Socket、Socket连接池

前言&#xff1a;作为一名开发人员我们经常会听到HTTP协议、TCP/IP协议、UDP协议、Socket、Socket长连接、Socket连接池等字眼&#xff0c;然而它们之间的关系、区别及原理并不是所有人都能理解清楚&#xff0c;这篇文章就从网络协议基础开始到Socket连接池&#xff0c;一步一步…

微服务基础知识

文章目录 微服务基础知识一、系统架构的演变1、单体应用架构2、垂直应用架构3、分布式SOA架构&#xff08;1&#xff09;什么是SOA&#xff08;2&#xff09;SOA架构 4、微服务架构5、SOA和微服务的关系&#xff08;1&#xff09;SOA&#xff08;2&#xff09;微服务架构 二、分…