Loading [MathJax]/jax/output/CommonHTML/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 删除。

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Qt音视频开发40-人脸识别离线版
上一篇文章写了在线调用人脸识别api进行处理,其实很多的客户需求是要求离线使用的,尤其是一些事业单位,严禁这些刷脸数据外泄上传到服务器,尽管各个厂家号称严格保密这些数据,但要阻止这些担心,唯一的解决办法就是设备离线使用,连个屁的网,不联网看你怎么上传,于是离线的人脸识别应用应运而生,比如我们手机上的识别就是本地库在运算,至于本地模型库估计会联网更新,以保持最新的状态。百度的离线人脸识别做的还行,看官网的sdk开发包,更新也是蛮快的,提供了windows、linux、android等版本。
feiyangqingyun
2020/10/27
1.1K0
Qt音视频开发40-人脸识别离线版
Qt音视频开发38-USB摄像头解码linux方案
做嵌入式linux上的开发很多年了,扳手指头算算,也起码9年了,陆陆续续做过很过诸如需要读取外接的USB摄像头或者CMOS摄像机的程序,实时采集视频,将图像传到前端,或者对图像进行人脸分析处理,最开始尝试的就是QCamera来处理,直接歇菜放弃,后面通过搜索发现都说要用v4l2视频框架来进行,于是东搞搞西搞搞尝试了很多次,终于整出来了,前后完善了好几年,无论写什么程序,发现要简简单单的实现基础的功能,都是非常快速而且容易的,但是想要做得好做得精,要花不少的精力时间去完善,适应各种不同的场景,比如就说用v4l2加载摄像头这个,需要指定设备文件来读取,而现场不可能让用户来给你指定,频繁的拔插也会导致设备文件名的改动,所以必须找到一个机制自动寻找你想要的摄像机的设备文件名称,比如开个定时器去调用linux命令来处理,甚至在不同的系统平台上要执行的命令还有些许的区别,如果本地有多个摄像头还需要区分左右之类的时候,那就只能通过断电先后上电顺序次序来区分了。
feiyangqingyun
2020/10/21
2.9K0
Qt音视频开发38-USB摄像头解码linux方案
Qt音视频开发43-人脸识别服务端
上一篇文章写道人脸识别客户端程序,当然要对应一个服务端程序,客户端才能正常运行,毕竟客户端程序需要与服务端程序进行交互他才能正常工作。通常人脸识别服务端程序需要和人脸识别的相关处理库在一起,这样他接收到相关的处理需求以后比如人脸识别的处理请求,需要调用本地的人脸识别库来处理,处理完成以后拿到结果,再组成协议的格式返回给客户端程序。
feiyangqingyun
2020/10/30
8800
Qt音视频开发43-人脸识别服务端
Qt音视频开发42-人脸识别客户端
人脸识别客户端程序,不需要和人脸识别相关的库在一起,而是通过协议通信来和人脸识别服务端通信交互,人脸识别客户端和服务端程序框架,主要是为了提供一套通用的框架,按照定好的协议,实现人脸识别的相关处理,很多厂家都会有也都会做类似的机制,以便第三方厂家或者自家的其他设备按照这个通信协议来处理,比如客户端程序可以在PC机上,也可以是网页,还可以是安卓客户端,前端设备比如人工访客机,访客机本地是不需要做人脸识别等处理的,而是发送到服务端处理完以后再拿到结果进行展示,这样就可以利用服务端强大的运算能力。
feiyangqingyun
2020/10/29
1K0
Qt音视频开发42-人脸识别客户端
Qt音视频开发17-海康sdk解码
在视频监控行业领域,海康当之无愧是老大,稳坐第一的宝座很多年了,近期需要将视频监控系统改成采用海康sdk的内核,于是特意去查阅了sdk的使用手册,sdk相关的文档和文件可以直接官网下载到,而且是经常更新的,目前提供了windows和linux上的,win上的sdk还是更新比较快而且完整的,但是在linux上的就不得不吐槽下了,很旧很旧的版本,不要看打包文件很新,其实里面的内容是很老的,不知道为啥官方不也同步更新linux上的sdk,也许现在linux上的需求还不是很多吧,但是随着国产化的大力推进,估计不久的将来linux上的也会慢慢的完善起来的,说不定官方早就有了此计划,还有一种个人的猜测是linux上的开发包估计官方自己内部用的新的,可能打算自己做linux上的各种客户端吧。
feiyangqingyun
2020/08/25
1.9K0
Qt音视频开发17-海康sdk解码
Qt音视频开发36-USB摄像头解码qcamera方案
除了监控专用的摄像头以外,有一些应用场景用的还是USB摄像头,甚至还有一些单片机或者开发板上用的CMOS摄像头,而Qt在嵌入式领域应用相当广,所以用Qt来读取加载显示USB摄像头和CMOS摄像头,也是非常多Qter做过的事情,qt本身就封装了qcamera类,专用于本地摄像头的读取显示,这个类主要是在windows系统和安卓系统比较好使,在嵌入式上歇菜,而且安卓上widget的qcamera也不好使,要用qml的camera才好使,所以开发人员很多时候,就是在找坑填坑,找到一种最佳的适中方案,比如我自己做过的一个手机app,需要调用手机的摄像头,前置后置还要能切换,抓图做一些处理,用的就是qml嵌入到widget,通过信号槽来通信。
feiyangqingyun
2020/10/18
2.5K0
Qt音视频开发36-USB摄像头解码qcamera方案
Qt音视频开发44-实时人脸框
在人脸识别到以后,需要在实时视频上将所有人脸框绘制出来,一把来说识别人脸会有多种选择,一个是识别最大人脸,这种场景主要用于刷脸门禁,还有一种是识别所有人脸,这种场景主要用于人脸识别摄像机,就是将画面中的所有人脸识别出来发给服务器,人脸框的数据主要是四个参数,左上角和右下角的位置,也可以说是x、y、width、height,可能有些做的比较好的还有倾斜角度,这个意义不是很大,人脸识别的速度一般都是飞快的,就算你用学习上用的opencv做识别也是非常快的,基本上都是毫秒级的响应,主要的耗时操作在特征值的提取,所以一般要求能够响应每个通道每秒钟25帧-30帧的画面绘制+人脸框的绘制,当然人脸框的数据可能会有多个。
feiyangqingyun
2020/11/01
1.3K0
Qt音视频开发44-实时人脸框
Qt音视频开发12-mpv解码播放
之前玩了vlc解码和ffmpeg解码,前阵子有个客户需要换成mpv解码,于是研究了下mpv的使用方法,自从用了mpv以后发现爱不释手,这玩意天生适合极客和程序员啊,居然将各种处理封装成了命令和属性调用,比如播放进度,你只需要读取属性time-pos即可,如果要读取音量只需要读取属性volume即可,设置音量就直接设置属性volume对应的值即可,我的乖乖,这太棒了棒极了,这不就是咱们梦寐以求的处理方式吗?你只需要封装几个通用的处理接口(读取属性mpv_get_property、设置属性mpv_set_property、执行命令mpv_command_node、设置参数mpv_set_option),就涵盖了绝大多数的功能,你说简单易用不,要的就是这种效果呢!!!
feiyangqingyun
2020/08/18
1.2K0
Qt音视频开发12-mpv解码播放
Qt音视频开发32-Onvif网络设置
用onvif协议来对设备的网络信息进行获取和设置,这个操作在众多的NVR产品中,用的很少,绝大部分用户都还是习惯直接通过摄像机的web页面进去配置,其实修改网络配置的功能在大部分的NVR中都是具备的,网络的参数主要包括IP地址、子网掩码、网关地址、DNS解析地址、NTP地址、网卡信息、网络协议等,这些都可以通过不同的onvif命令来获取和设置,一直没有搞懂为啥这些要分开不同的命令去处理,其实大可以合并成一个命令嘛,搞得设置个网络信息还要post好多次的数据才行。
feiyangqingyun
2020/10/12
1.1K0
Qt音视频开发32-Onvif网络设置
Qt音视频开发5-vlc事件订阅
事件订阅可以拿到文件长度、播放进度、播放状态改变等信息,vlc的事件订阅机制封装的比较友好,只需要先创建一个事件管理器,然后逐个订阅自己感兴趣的需要的事件,不感兴趣的可以不要订阅,只有订阅了的事件才能在事件回调中拿到,所以如果在事件回调中发现一些事件没有拿到,首先要检查下到底订阅了没有,所有事件的枚举在libvlc_events.h头文件中可以查阅到,都用的是通俗易懂的全英文单词描述,有过基本英语能力的开发人员都能看懂。
feiyangqingyun
2020/08/07
7610
Qt音视频开发5-vlc事件订阅
Qt音视频开发18-海康sdk回调
海康sdk显示实时视频流除了支持句柄方式以外,也支持回调的方式拿到每一张图片自己绘制处理,当然回调除了拿到视频数据,其实音频数据也一块拿到了,自行调用音频设备播放就行,关于海康sdk回调这块,还着实折腾了一阵子才搞定,可能最开始没有参照提供的demo以及没有彻底的搜索吧,只是单单看sdk的文档折腾来折腾去的,搞了一星期居然没搞定,后面找到了正确的办法才发现,原来就差一点点一丢丢呢,这又让我联想到很多事情,包括生活中的事情,不都是如此么?当你铆足了劲,试验搞了各种办法,快要精疲力尽放弃的时候,其实此时离成功就差一步了,真的就差那么一丢丢,处理生活中的很多事情也是如此,所以很多时候如果方向对了,坚持过努力过,还不行的话,再努力一把估计就ok了。
feiyangqingyun
2020/08/26
2K0
Qt音视频开发18-海康sdk回调
Qt音视频开发39-人脸识别在线版
关于人脸识别这块,前些年不要太火,哪怕是到了今天依然火的一塌糊涂,什么玩意都要跟人脸识别搭个边,这东西应该只是人工智能的一个很小的部分,人脸识别光从字面上理解就是识别出人脸区域,其实背后真正的处理是拿到人脸区域图片,提取人脸特征值,再用这些特征值去做比对分析处理,识别出到底是谁,国内厂家也不少,比拼的就是准确度误报率,速度无非就是靠堆硬件来,什么VPU各种并行运算都堆上去,速度杠杠的,好多厂家都做到了几个毫秒的级别,估计很多厂家都是在开源的基础上加上了自家的算法,一直跑呀跑的整出了符合自家算法的人脸模型文件,比如百度的人脸识别模型文件,经过好几年的发展,越来越大越来越细越来越准。
feiyangqingyun
2020/10/26
1.8K0
Qt音视频开发39-人脸识别在线版
Qt音视频开发1-vlc解码播放
最开始接触视频监控这块的时候,用的就是vlc作为解码的内核,主要是因为vlc使用简单方便,直接传入一个句柄即可,简单几行代码就可以实现一个视频流播放,很适合初学者使用,也推荐初学者用qt+vlc来做播放器,提供的接口还是非常友好的,而且门类特别多,想要获取媒体文件的各种信息比如宽高,设置宽高比等,直接调用接口函数传入参数就能设置。
feiyangqingyun
2020/08/02
1.3K0
Qt音视频开发1-vlc解码播放
Qt音视频开发21-通用硬解码
硬件解码是图形芯片厂家提出的用GPU资源解码视频流的方案,与之相对的是软解,也就是传统的用CPU承担解码工作的方案;优点是效率高,功耗低、热功耗低,缺点是缺乏有力的支持(包括滤镜、字幕等),局限性较大(例如打开硬件解码后PC的节能方面的功能失效cnq等),设置较为复杂;需要硬件有硬件解码模块、相关的驱动配合、合适的播放软件以及对播放软件正确的设置,缺一而不能开启硬件解码功能,主流的硬件解码方案由Intel、AMD-ATI以及Nvdia推出。
feiyangqingyun
2020/08/31
1.8K0
Qt音视频开发21-通用硬解码
Qt音视频开发23-通用视频控件
在之前做的视频监控系统中,根据不同的用户需要,做了好多种视频监控内核,有ffmpeg内核的,有vlc内核的,有mpv内核的,还有海康sdk内核的,为了做成通用的功能,不同内核很方便的切换,比如pro直接改一个DEFINE的变量名,所以需要将各种内核的使用方法做成一样的接口,这样看起来就很整齐,所以后面特意提炼了一个通用的视频控件,该控件没有具体的视频播放控制功能,需要根据不同的内核去调用具体的方法实现,后面还需要增加大华sdk或者其他第三方厂家的协议的时候,直接套用这个通用视频控件即可,以后增加新的监控内核,可以省下很多工作量,基本上只需要做内核解析就行,其余通用接口和绘制图像直接交给通用视频控件就行。
feiyangqingyun
2020/09/02
1.4K0
Qt音视频开发23-通用视频控件
Qt音视频开发27-Onvif设备搜索
最近业余时间主要研究音视频开发这块,前面的文章写了好多种视频监控内核,一旦将这些内核搞定以后,视频监控的相关功能水到渠成。做视频监控系统,绕不过onvif这玩意,这玩意主要就是为了统一一个大概的标准,能够对各个厂家的监控设备进行常用的一些操作,比如搜索、获取信息、云台控制、事件订阅、抓拍图片等,如果没有这个规范,那么各个厂家都各自为政,需要用私有的sdk去处理,这样就很麻烦很惨了,几十个厂家就需要几十个sdk,对于程序员来说简直是灾难,想想就很恐怖的事情,哪个程序员不想多活几年!
feiyangqingyun
2020/10/04
1.1K0
Qt音视频开发27-Onvif设备搜索
Qt音视频开发7-ffmpeg音频播放
之前用ffmpeg解码出来了音频,只是做了存储部分,比如存储成aac文件,播放的话早期用的是sdl来播放音频,自从Qt5以后提供了QAudioOutput来播放输入的音频数据,就更加方便了,可以直接将解码好的音频数据写入就能播放了,这些就少了个学习sdl的成本,而且和Qt就更加融合,不需要额外的第三方库,解码好的视频,其实就是一张张图片数据,可以直接用QPainter绘制或者QOpenGlWidget通过GPU显示,解码好的音频用QAudioOutput播放,这对于很多初学者来说,是个很好的消息,完美。
feiyangqingyun
2020/08/10
1.6K0
Qt音视频开发7-ffmpeg音频播放
Qt音视频开发31-Onvif抓拍图片
抓拍是个很重要的功能,比如在报警视频联动中需要一张实时的图片,很多SDK不提供抓拍功能,而通过预览抓图,得到的图片已不具有实时性,那如何得到实时的图片呢?现在的IPC基本上都支持ONVIF协议,ONVIF协议除了提供RTSP的URL外,其实也给出了抓拍的URL,从Media的GetSnapshotUri获取。
feiyangqingyun
2020/10/10
1.4K0
Qt音视频开发31-Onvif抓拍图片
Qt编写的项目作品24-人脸识别综合应用(在线+离线+嵌入式)
一、功能特点 支持的功能包括人脸识别、人脸比对、人脸搜索、活体检测等。 在线版还支持身份证、驾驶证、行驶证、银行卡等识别。 在线版的协议支持百度、旷视,离线版的支持百度,可定制。 除了支持X86架构,还支持嵌入式linux比如contex-A9、树莓派等。 每个功能的执行除了返回结果还返回执行用时时间。 多线程处理,通过type控制当前处理类型。 支持单张图片检索相似度最高的图片。 支持指定目录图片用来生成人脸特征值文件。 可设置等待处理图片队列中的数量。 每次执行都有成功或者失败的信号返回。 人脸搜索的返
feiyangqingyun
2020/05/04
1.1K0
Qt编写的项目作品24-人脸识别综合应用(在线+离线+嵌入式)
Qt音视频开发45-视频传输TCP版
做音视频开发,会遇到将音视频重新转发出去的需求,当然终极大法是推流转发,还有一些简单的场景是直接自定义协议将视频传出去就行,局域网的话速度还是不错的。很多年前就做过类似的项目,无非就是将本地的图片上传到服务器,就这么简单,其实用http的post上传比较简单容易,无需自定义协议,直接设置好二进制数据即可,而采用TCP或者UDP通信的话,必须自定义协议,因为不知道什么时候数据接收完了是完整的图片数据,可能同时在发送很多图片数据,而且还不能区分收到的图片是哪个客户端发来的,TCP长连接的话,还需要有心跳来检测连接,所以必须自定义一套协议来支撑通信,这套协议采用的是上海监管平台的通信协议格式,拓展性比较强,其中头部信息包括了类型+当前完整包的数据长度,这个类型就是通信协议的标识,这样下次来一个其他类型的比如楼宇对讲可以叫IDOOR,服务端根据这个标识就能知道采用何种解析算法来处理后面的数据,而当前完整包的数据长度可以用来处理收到的数据,只有该长度的数据才表示接收完成一个完整的图片数据,再去解码处理。当传输的图片到了一定速度的时候比如一秒钟传输20张图片,其实就相当于传输视频了,一般人的肉眼看到一秒钟20张图片基本上认识就是视频了。
feiyangqingyun
2020/11/03
1.3K0
Qt音视频开发45-视频传输TCP版
相关推荐
Qt音视频开发40-人脸识别离线版
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档