Loading [MathJax]/jax/input/TeX/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Qt音视频开发41-人脸识别嵌入式

Qt音视频开发41-人脸识别嵌入式

原创
作者头像
feiyangqingyun
修改于 2020-10-28 02:57:18
修改于 2020-10-28 02:57:18
1.1K0
举报
文章被收录于专栏:Qt项目实战Qt项目实战

一、前言

大概几年前搞过一套嵌入式linux上的人脸识别程序,当然人脸识别的核心算法并不是自己开发的,关于人脸识别算法这一块,虽然有众多的开源库可以用,甚至还可以用opencv搞算法训练深度学习之类的,个人认为始终达不到准确度的要求,尤其是人脸比对的准确度,这个需要专业的人脸训练模型才行。目前市面上绝大部分的人脸识别库提供的都是X86的或者安卓ios的库,并没有嵌入式linux的库,估计一方面因为嵌入式linux跑的板子性能比较低,还有一个就是依赖特定编译器,版本众多难以提供,市场也小,所以大部分的厂家都没有提供嵌入式linux的开发包,这个就比较鸡肋,所以很多终端厂家最终弃用linux而选用安卓作为载体系统,这样就可以用上高大上的人脸识别库了,比如萤火虫开发板,RK3288 RK3399等。

记得当时还特意搞了一整套的非常详细的通信协议,产品也初步成型,大概的设备有人脸识别终端、双目门禁、人工访客机、自助访客机、人脸比对服务器等,也试运行了一些小区,效果还行,不过在抗逆光和晚上的情况下效果不是很好,当然这是所有人脸识别设备的通病,必须依赖补光或者调整安装位置增加抗逆光摄像机来处理,这样一来对施工就有要求了增加了复杂度,设备成本也上来了,对于小终端厂商来说,这个要选择一个平衡点才行,只有用户愿意付出对应的成本才提供对应的版本。

通信方式及端口:

  • 客户端和服务端等设备统一提供web访问修改配置,端口6660。
  • 人工访客机客户端与人工访客机服务端通信采用TCP短连接,通信端口6661。
  • 自助访客机客户端与自助访客机服务端通信采用TCP长连接,通信端口6661。
  • 人脸识别比对数据库服务器采用TCP长连接,通信端口6662。
  • 服务端与数据库服务器通信采用TCP长连接,通信端口6666。
  • 数据库服务器下发人脸通行证数据采用TCP短连接,通信端口6667。
  • 电脑PC端下发配置到双目门禁采用TCP短连接,通信端口6668。
  • 双目门禁与数据库服务器通信采用TCP长连接,通信端口6669。
  • 双目门禁电脑客户端升级通信采用TCP短连接,通信端口6670。
  • 检测测试与手机app或者其他客户端通信采用TCP长连接,通信端口6671。

二、功能特点

  1. 支持的功能包括人脸识别、人脸比对、人脸搜索、活体检测等。
  2. 在线版还支持身份证、驾驶证、行驶证、银行卡等识别。
  3. 在线版的协议支持百度、旷视,离线版的支持百度,可定制。
  4. 除了支持X86架构,还支持嵌入式linux比如contex-A9、树莓派等。
  5. 每个功能的执行除了返回结果还返回执行用时时间。
  6. 多线程处理,通过type控制当前处理类型。
  7. 支持单张图片检索相似度最高的图片。
  8. 支持指定目录图片用来生成人脸特征值文件。
  9. 可设置等待处理图片队列中的数量。
  10. 每次执行都有成功或者失败的信号返回。
  11. 人脸搜索的返回结果包含了原图+最大相似度图+相似度等。
  12. 人脸比对同时支持两张图片和两个特征值比对。
  13. 相关功能自定义一套协议用于客户端和服务端,可以通过TCP通信进行交互。
  14. 自定义人脸识别协议非常适用于中心一台服务器,现场若干设备请求的场景。
  15. 每个模块全部是独立的一个类,代码整洁、注释完善。

三、效果图

video_face4.gif
video_face4.gif

四、相关站点

  1. 国内站点:https://gitee.com/feiyangqingyun/QWidgetDemo
  2. 国际站点:https://github.com/feiyangqingyun/QWidgetDemo
  3. 个人主页:https://blog.csdn.net/feiyangqingyun
  4. 知乎主页:https://www.zhihu.com/people/feiyangqingyun/
  5. 体验地址:https://blog.csdn.net/feiyangqingyun/article/details/97565652

五、核心代码

代码语言:txt
AI代码解释
复制
void FaceLocalArm::imgToBgr(const QImage &img, quint8 *bgr, int w, int h)
{
    for (int i = 0; i < h; ++i) {
        const quint8 *scanline = img.scanLine(i);
        for (int j = 0; j < w; ++j) {
            *bgr++ = scanline[j * 3 + 0];
            *bgr++ = scanline[j * 3 + 1];
            *bgr++ = scanline[j * 3 + 2];
        }
    }
}

void FaceLocalArm::bgrToYuv(quint8 *yuv, const quint8 *bgr, int w, int h)
{
    int b, g, r;
    for (int i = 0; i < w * h; ++i) {
        b = bgr[3 * i + 0];
        g = bgr[3 * i + 1];
        r = bgr[3 * i + 2];
        yuv[i] = (quint8)((r * 30 + g * 59 + b * 11 + 50) / 100);
    }
}

void FaceLocalArm::init()
{
    //如果已经正常则无需初始化
    if (isOk) {
        return;
    }
#ifdef __arm__
    int res = CRface::FaceDetect_Init_ColorReco(sdkPath.toStdString());
    if (res != 1) {
        qDebug() << TIMEMS << QString("FaceDetect_Init_ColorReco error: %1").arg(res);
    } else {
        qDebug() << TIMEMS << "FaceDetect_Init_ColorReco ok";
        res = CRface::FaceReco_Init_ColorReco(sdkPath.toStdString());
        if (res != 1) {
            qDebug() << TIMEMS << QString("FaceReco_Init_ColorReco error: %1").arg(res);
        } else {
            isOk = true;
            qDebug() << TIMEMS << "FaceReco_Init_ColorReco ok";
        }
    }

    emit sdkInitFinsh(isOk);
#endif
}

bool FaceLocalArm::getFaceRect(const QString &flag, const QImage &img, QRect &rect, int &msec)
{
    if (!isOk) {
        return false;
    }
#ifdef __arm__
    //qDebug() << TIMEMS << flag << "getFaceRect";

    QTime time;
    if (countTime) {
        time.start();
    }

    int w = img.width();
    int h = img.height();

    //这里有隐患,如果图片像素特别大会崩溃,应该改为quint8 *bgr=(quint8 *)calloc(w * h * 3, 1);然后后面free(bgr);
    quint8 yuv[w * h];
    quint8 bgr[w * h * 3];
    imgToBgr(img, bgr, w, h);

    int facebox[32 * 5];
    bgrToYuv(yuv, bgr, w, h);
    facebox[0] = 0;
    int result = 0;
    if (findFast) {
        result = CRface::FaceDetect_Fast_ColorReco(yuv, w, h, facebox, true);
    } else {
        result = CRface::FaceDetect_Normal_ColorReco(yuv, w, h, facebox, true, w / percent);
    }

    if (result == 1) {
        rect = QRect(facebox[1], facebox[2], facebox[3], facebox[4]);
        msec = getTime(time);
        return true;
    }
#endif
    return false;
}

bool FaceLocalArm::getFaceFeature(const QString &flag, const QImage &img, QList<float> &feature, int &msec)
{
    if (!isOk) {
        return false;
    }
#ifdef __arm__
    //qDebug() << TIMEMS << flag << "getFaceFeature" << img.width() << img.height() << img.size();

    QTime time;
    if (countTime) {
        time.start();
    }

    int w = img.width();
    int h = img.height();

    //这里有隐患,如果图片像素特别大会崩溃,应该改为quint8 *bgr=(quint8 *)calloc(w * h * 3, 1);然后后面free(bgr);
    quint8 yuv[w * h];
    quint8 bgr[w * h * 3];
    imgToBgr(img, bgr, w, h);

    int facebox[32 * 5];
    bgrToYuv(yuv, bgr, w, h);
    facebox[0] = 0;
    int result = 0;
    if (findFast) {
        result = CRface::FaceDetect_Fast_ColorReco(yuv, w, h, facebox, true);
    } else {
        result = CRface::FaceDetect_Normal_ColorReco(yuv, w, h, facebox, true, w / percent);
    }

    if (result == 1) {
        QRect rect = QRect(facebox[1], facebox[2], facebox[3], facebox[4]);
        msec = getTime(time);
        emit receiveFaceRect(flag, rect, msec);

        float fea[256];
        int result = CRface::FaceReco_Extract_ColorReco(bgr, w, h, facebox + 1, fea);

        if (result == 256) {
            feature.clear();
            for (int i = 0; i < 256; i++) {
                feature.append(fea[i]);
            }

            msec = getTime(time);
            return true;
        }
    } else {
        emit receiveFaceRectFail(flag);
    }
#endif
    return false;
}

float FaceLocalArm::getFaceCompare(const QString &flag, const QList<float> &feature1, const QList<float> &feature2)
{
    if (!isOk) {
        return 0;
    }
#ifdef __arm__
    //qDebug() << TIMEMS << flag << "getFaceCompareXXX";

    float fea1[256], fea2[256];
    for (int i = 0; i < 256; i++) {
        fea1[i] = feature1.at(i);
        fea2[i] = feature2.at(i);
    }

    float result = CRface::FaceReco_Match_ColorReco(fea1, fea2);
    result = result * 100;
    //过滤非法的值
    result = result > 100 ? 0 : result;
    return result;
#endif

    return 0;
}

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
​测开必备,推荐几款前端性能测试工具、神器
我们在使用网站过程中,经常会遇到慢的问题,为了找到原因,一般需要借助工具进行检测,通过工具,可以检测出前端站点加载资源的相关详细情况。
测试开发技术
2021/02/02
2.2K0
​测开必备,推荐几款前端性能测试工具、神器
《前端性能优化秘籍:打造极致用户体验》
在当下,网站和应用的性能表现直接关乎用户去留。快速加载、流畅交互的页面能让用户沉浸其中,反之,缓慢的响应速度则会让他们毫不犹豫地离开。对于前端开发者而言,性能优化不仅是技术追求,更是提升用户体验、增强产品竞争力的关键所在。接下来,就让我们深入探寻前端性能优化的宝藏秘籍。
程序员阿伟
2025/04/17
2480
《前端性能优化秘籍:打造极致用户体验》
28. 精读《2017前端性能优化备忘录》
本期精读的文章是:Front End Performance Checklist 2017
黄子毅
2022/03/14
5730
28. 精读《2017前端性能优化备忘录》
测开必备,推荐几款前端性能测试工具、神器
我们在使用网站过程中,经常会遇到慢的问题,为了找到原因,一般需要借助工具进行检测,通过工具,可以检测出前端站点加载资源的相关详细情况。
测试开发技术
2021/02/07
4.2K0
前端性能分析工具利器
作者:basinwang,腾讯 PCG 前端开发工程师 大型项目容易遇到性能问题,一般来说,当我们遇到性能瓶颈的时候,才会开始去进行相应的分析。分析的方向除了业务本身的特点相关之外,常见的还可以借助一些工具来发现问题。本文主要介绍前端性能分析可以怎么走~ 前端性能分析工具(Chrome DevTools) 一般来说,前端的性能分析通常可以从时间和空间两个角度来进行: 时间:常见耗时,如页面加载耗时、渲染耗时、网络耗时、脚本执行耗时等 空间:资源占用,包括 CPU 占用、内存占用、本地缓存占用等 那么,
腾讯技术工程官方号
2020/09/03
3.1K1
H5前端性能测试快速入门
前言 说到H5测试,对于做WEB测试的同学来说再熟悉不过了,它包括页H5功能测试,前端性能测试,浏览器兼容性能测试,以及服务端性能测试。那本文谈到的则是H5前端性能测试,并希望通过阅读本文后,能够知道:H5前端性能测试什么?如何发现问题以及相应的优化规则。 一、浏览器渲染引擎 浏览器是Html解析和页面最终展示的工具,所以测试H5前理解浏览器的工作原理是必不可少的,具体可参考《浏览器工作原理》。 浏览器的主要功能 浏览器的主要功能是将用户选择的web资源呈现出
腾讯移动品质中心TMQ
2018/02/05
2K0
H5前端性能测试快速入门
前端性能优化:构建快速且流畅的Web体验
在现代Web开发中,性能优化是提升用户体验的关键因素之一。随着网络环境的变化和用户需求的增长,如何让Web应用在各种设备上快速加载并流畅运行变得尤为重要。本文将深入探讨前端性能优化的各种技术和策略,帮助开发者构建更快、更高效的Web应用。
井九
2024/10/12
3820
前端性能优化:构建快速且流畅的Web体验
前端代码性能优化【提升网页加载与响应速度的关键方法】
随着现代Web应用的复杂性不断增加,前端代码的性能优化变得越来越重要。一个加载缓慢或响应迟钝的网页会直接影响用户体验,甚至导致用户流失。在这篇文章中,我们将深入探讨前端代码性能优化的关键方法,并分享几个常见的前端性能案例,帮助你提升网页的加载和响应速度。
一键难忘
2024/08/11
1.4K0
网站测速性能测试深入浅出教程[附15款常用网站测速工具
讨论到WordPress网站,必须要重视到速度很重要。这是一个事实。为什么?首先,网站速度是Google算法甚至所有搜索引擎算法的重要因素。加载速度足够快的网站才有可能会在搜索引擎中获得更高的排名,并吸引更多的访问者。其次,这也是用户体验考虑因素。如果网站加载速度足够快,访问者更有可能留下来,阅读您的内容,并最终转换。换句话说,作为一个网站管理员/运营者,都应该渴望更快的网站加载速度,没有任何一个赛车手不对高性能车“趋之若骛”。
开心分享
2020/08/05
4K0
网站测速性能测试深入浅出教程[附15款常用网站测速工具
【综合篇】Web前端性能优化原理问题
想要成为一名合格的Web前端工程师,Web前端性能优化是一个必须要掌握的知识,那么应该怎么进行Web前端性能优化呢?--达达前端
达达前端
2020/02/18
1.8K0
【综合篇】Web前端性能优化原理问题
前端性能分析工具-Lighthouse
对于前端开发人员来说,除了实现页面功能外,那就是页面的性能响应问题也要关注。同样对于测试人员在进行性能测试时,也要关注前端页面的性能指标。测试前端性能市面上可以用到的工具也比较多,比如可以用 HttpWatch 进行页面的抓取与分析,或者也可以使用抓包工具如 Fiddler 抓接口的形式进行分析。
wangmcn
2022/07/26
1.2K0
前端性能分析工具-Lighthouse
前端性能优化 —— 前端性能分析
作者:ouven https://my.oschina.net/zhangstephen/blog/1601380 前端性能优化是一个很宽泛的概念,本书前面的部分也多多少少提到一些前端优化方法,这也是我们一直在关注的一件重要事情。配合各种方式、手段、辅助系统,前端优化的最终目的都是提升用户体验,改善页面性能,我们常常竭尽全力进行前端页面优化,但却忽略了这样做的效果和意义。先不急于探究前端优化具体可以怎样去做,先看看什么是前端性能,应该怎样去了解和评价前端页面的性能。 通常前端性能可以认为是用户获取所需要页面
前端教程
2018/03/05
2.5K0
前端性能优化 —— 前端性能分析
8个值得推荐的用于前端开发的性能分析工具
原文链接:https://blog.bitsrc.io/performance-analysis-tools-for-front-end-development-a7b3c1488876,作者:Mahdhi Rezvi
程序员法医
2022/08/11
3.4K0
8个值得推荐的用于前端开发的性能分析工具
2020前端性能优化清单(六)
通过在服务器上启用 OCSP stapling[2],可以加快 TLS 握手的速度。联机证书状态协议(OCSP)被创建为证书吊销列表(CRL)协议的替代品。两种协议都用于检查 SSL 证书是否已被吊销。但是,OCSP 协议不需要浏览器花时间下载和搜索证书信息列表,因此减少了握手所需的时间。
WecTeam
2020/05/06
1.4K0
2020前端性能优化清单(六)
前端性能优化
本文主要考虑客户端性能、服务器端和网络性能,内容框架来自Yahoo Developer Network,包含 7 个类别共 35 条前端性能优化最佳实践,在此基础上补充了一些相关或者更符合主流技术的内容。
grain先森
2019/03/28
2.1K0
前端性能优化
监控与日志管理工具的应用与集成【提升前端开发效率】
前端性能优化是提升用户体验和站点性能的关键因素。前端开发者在开发过程中,不仅需要编写高效的代码,还需要借助各种工具来监控和优化性能。这篇文章将介绍一些能够帮助前端开发者提高开发效率的工具,重点分享如何使用监控工具和日志管理工具。
一键难忘
2024/07/27
8110
Web前端性能优化工具
可以查看到网站所有资源的请求情况,包括加载时间、尺寸大小、优先级设置及HTTP缓存触发情况等信息,从而帮助我们发现可能由于未进行有效压缩而导致资源尺寸过大的问题,或者未合理配置缓存策略导致二次请求加载时间过长的问题等
yeedomliu
2022/12/03
1.1K0
Web前端性能优化工具
前端性能优化秘籍:让你的网页飞起来
作为一名前端开发者,遇到页面加载慢、卡顿、白屏这些问题再正常不过了。毕竟,用户的耐心就像天气一样多变——一旦页面超过 3 秒 还没加载完,他们可能就会毫不犹豫地关掉网页,去找别的替代品。
Echo_Wish
2025/03/16
1030
前端性能优化秘籍:让你的网页飞起来
相关推荐
​测开必备,推荐几款前端性能测试工具、神器
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档