千家信息网

Qt怎么实现人脸识别客户端

发表于:2025-12-01 作者:千家信息网编辑
千家信息网最后更新 2025年12月01日,这篇文章主要讲解了"Qt怎么实现人脸识别客户端",文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习"Qt怎么实现人脸识别客户端"吧!一、前言人脸识别客户端程序
千家信息网最后更新 2025年12月01日Qt怎么实现人脸识别客户端

这篇文章主要讲解了"Qt怎么实现人脸识别客户端",文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习"Qt怎么实现人脸识别客户端"吧!

一、前言

人脸识别客户端程序,不需要和人脸识别相关的库在一起,而是通过协议通信来和人脸识别服务端通信交互,人脸识别客户端和服务端程序框架,主要是为了提供一套通用的框架,按照定好的协议,实现人脸识别的相关处理,很多厂家都会有也都会做类似的机制,以便第三方厂家或者自家的其他设备按照这个通信协议来处理,比如客户端程序可以在PC机上,也可以是网页,还可以是安卓客户端,前端设备比如人工访客机,访客机本地是不需要做人脸识别等处理的,而是发送到服务端处理完以后再拿到结果进行展示,这样就可以利用服务端强大的运算能力。

自定义人脸识别协议功能:

  1. 离线使用,同时支持百度的离线包和嵌入式linux人脸识别静态库。

  2. 支持多个连接并发,自动排队处理,返回的时候带上唯一标识区分。

  3. 传入单张图片返回人脸区域。

  4. 传入单张图片返回人脸特征值。

  5. 传入单张图片或者多张图片返回是否是活体。

  6. 传入两张图片返回比对结果。

  7. 传入两个特征值返回比对结果。

  8. 传入单张图片添加人脸。

  9. 指定唯一标识符删除人脸。

  10. 传入单张照片返回相似度最大的人脸信息。

  11. 修改人脸服务的配置参数比如是否快速查找、人脸占比等。

二、功能特点

  1. 支持的功能包括人脸识别、人脸比对、人脸搜索、活体检测等。

  2. 在线版还支持身份证、驾驶证、行驶证、银行卡等识别。

  3. 在线版的协议支持百度、旷视,离线版的支持百度,可定制。

  4. 除了支持X86架构,还支持嵌入式linux比如contex-A9、树莓派等。

  5. 每个功能的执行除了返回结果还返回执行用时时间。

  6. 多线程处理,通过type控制当前处理类型。

  7. 支持单张图片检索相似度最高的图片。

  8. 支持指定目录图片用来生成人脸特征值文件。

  9. 可设置等待处理图片队列中的数量。

  10. 每次执行都有成功或者失败的信号返回。

  11. 人脸搜索的返回结果包含了原图+最大相似度图+相似度等。

  12. 人脸比对同时支持两张图片和两个特征值比对。

  13. 相关功能自定义一套协议用于客户端和服务端,可以通过TCP通信进行交互。

  14. 自定义人脸识别协议非常适用于中心一台服务器,现场若干设备请求的场景。

  15. 每个模块全部是独立的一个类,代码整洁、注释完善。

三、效果图

四、核心代码

FaceSdkClient::FaceSdkClient(QObject *parent) : QObject(parent){    isOk = false;    timeout = 10;    lastTime = QDateTime::currentDateTime();    //随机生成IP用于测试    clientIP = QString("192.168.1.%1").arg(qrand() % 255);    serverIP = "192.168.1.239";    serverPort = 6662;    //实例化连接对象    tcpSocket = new QTcpSocket(this);    connect(tcpSocket, SIGNAL(connected()), this, SLOT(connected()));    connect(tcpSocket, SIGNAL(disconnected()), this, SLOT(disconnected()));    connect(tcpSocket, SIGNAL(readyRead()), this, SLOT(readData()));    //定时器处理数据    timerData = new QTimer(this);    connect(timerData, SIGNAL(timeout()), this, SLOT(checkData()));    timerData->setInterval(100);    //定时器处理重连    timerConn = new QTimer(this);    connect(timerConn, SIGNAL(timeout()), this, SLOT(checkConn()));    timerConn->setInterval(3000);    //定时器发送心跳    timerHeart = new QTimer(this);    connect(timerHeart, SIGNAL(timeout()), this, SLOT(sendHeart()));    timerHeart->setInterval(2000);}void FaceSdkClient::connected(){    isOk = true;    sendHeart();}void FaceSdkClient::disconnected(){    isOk = false;    emit receiveAnaly(serverIP, "服务器断开");}void FaceSdkClient::checkConn(){    QDateTime now = QDateTime::currentDateTime();    if (lastTime.secsTo(now) >= timeout) {        isOk = false;        start();        emit receiveAnaly(serverIP, "重连服务器");    }}void FaceSdkClient::readData(){    lastTime = QDateTime::currentDateTime();    QMutexLocker locker(&mutex);    buffer.append(tcpSocket->readAll());}void FaceSdkClient::checkData(){    QMutexLocker locker(&mutex);    QDomDocument dom;    if (!DeviceFun::getReceiveXmlData(buffer, dom, "IFACE:", 10)) {        return;    }    //逐个取出节点判断数据    emit receiveData(serverIP, dom.toString());    QDomElement element = dom.documentElement();    if (element.tagName() == "FaceServer") {        //查找时间字段属性        QString nowTime = element.attribute("NowTime");        QString year, month, day, hour, min, sec;        DeviceFun::getNowTime(nowTime, year, month, day, hour, min, sec);        //QUIHelper::setSystemDateTime(year, month, day, hour, min, sec);        //根据子节点处理        QDomNode childNode = element.firstChild();        QString name = childNode.nodeName();        QString value = element.text();        //qDebug() << TIMEMS << name << value;        //取出faceID和耗时        element = childNode.toElement();        QString faceID = element.attribute("FaceID");        int msec = element.attribute("TimeUsed").toInt();        if (name == "Msg") {            if (value.startsWith("Init Face Finsh")) {                emit receiveFaceFeatureFinsh();            } else if (value.startsWith("Find Face Rect Fail")) {                emit receiveFaceRectFail(faceID);            } else if (value.startsWith("Find Face Feature Fail")) {                emit receiveFaceFeatureFail(faceID);            } else if (value.startsWith("Find Face Compare Fail")) {                emit receiveFaceCompareFail(faceID);            } else if (value.startsWith("Find Face Live Fail")) {                emit receiveFaceLiveFail(faceID);            } else if (value.startsWith("Image Size Is Too Large")) {                emit receiveAnaly(serverIP, "图片尺寸过大");            } else {                emit receiveAnaly(serverIP, value);            }        } else if (name == "FaceRect") {            QStringList list = value.split(",");            QRect faceRect(list.at(0).toInt(), list.at(1).toInt(), list.at(2).toInt(), list.at(3).toInt());            emit receiveFaceRect(faceID, faceRect, msec);        } else if (name == "FaceFeature") {            QStringList list = value.split("|");            QList feature;            for (int i = 0; i < 256; i++) {                feature << list.at(i).toFloat();            }            emit receiveFaceFeature(faceID, feature, msec);        } else if (name == "FaceLive") {            float result = element.attribute("Result").toFloat();            emit receiveFaceLive(faceID, result, msec);        } else if (name == "FaceCompare") {            float result = element.attribute("Result").toFloat();            emit receiveFaceCompare(faceID, result, msec);        } else if (name == "FaceCompareOne") {            QStringList list = value.split("|");            QImage image1 = DeviceFun::getImage(list.at(0));            QImage image2 = DeviceFun::getImage(list.at(1));            QString targetName = element.attribute("TargetName");            float result = element.attribute("Result").toFloat();            emit receiveFaceCompareOne(faceID, image1, image2, targetName, result, msec);        } else if (name == "FaceConfig") {            QString findFast = element.attribute("FindFast");            QString facePercent = element.attribute("FacePercent");            QString info = QString("模式: %1  比例: %2").arg(findFast == "true" ? "快速模式" : "正常模式").arg(facePercent);            emit receiveAnaly(serverIP, "人脸配置  " + info);        } else {            emit receiveAnaly(serverIP, "心跳回复");        }    }}void FaceSdkClient::setClientIP(const QString &clientIP){    this->clientIP = clientIP;}void FaceSdkClient::setServerIP(const QString &serverIP){    this->serverIP = serverIP;}void FaceSdkClient::setServerPort(int serverPort){    this->serverPort = serverPort;}bool FaceSdkClient::start(){    tcpSocket->abort();    tcpSocket->connectToHost(serverIP, serverPort);    timerData->start();    timerConn->start();    timerHeart->start();    return true;}void FaceSdkClient::stop(){    tcpSocket->disconnectFromHost();    timerData->stop();    timerConn->stop();    timerHeart->stop();}void FaceSdkClient::sendData(const QString &body){    if (!isOk) {        return;    }    //构建xml字符串    QStringList list;    list.append(QString("").arg(clientIP));    list.append(body);    list.append("");    QString data = DeviceFun::getSendXmlData(list.join(""), "IFACE:");    tcpSocket->write(data.toUtf8());    emit sendData(clientIP, data);}void FaceSdkClient::sendHeart(){    if (!isOk) {        return;    }    sendData("");    emit sendAnaly(clientIP, "发送心跳");}void FaceSdkClient::sendFindFace(const QString &faceID, const QImage &image){    if (!isOk) {        return;    }    QString data = QString("%2").arg(faceID).arg(DeviceFun::getImageData(image));    sendData(data);    emit sendAnaly(clientIP, "请求人脸区域");}void FaceSdkClient::sendFindFeature(const QString &faceID, const QImage &image){    if (!isOk) {        return;    }    QString data = QString("%2").arg(faceID).arg(DeviceFun::getImageData(image));    sendData(data);    emit sendAnaly(clientIP, "请求人脸特征");}void FaceSdkClient::sendFindLive(const QString &faceID, const QImage &image){    if (!isOk) {        return;    }    QString data = QString("%2").arg(faceID).arg(DeviceFun::getImageData(image));    sendData(data);    emit sendAnaly(clientIP, "请求活体检测");}void FaceSdkClient::sendCompareByImage(const QString &faceID1, const QImage &image1,                                       const QString &faceID2, const QImage &image2){    if (!isOk) {        return;    }    QStringList list;    list.append("");    list.append(QString("%2").arg(faceID1).arg(DeviceFun::getImageData(image1)));    list.append(QString("%2").arg(faceID2).arg(DeviceFun::getImageData(image2)));    list.append("");    sendData(list.join(""));    emit sendAnaly(clientIP, "请求人脸比对");}void FaceSdkClient::sendCompareByFeature(const QString &faceID1, const QString &feature1,        const QString &faceID2, const QString &feature2){    if (!isOk) {        return;    }    QStringList list;    list.append("");    list.append(QString("%2").arg(faceID1).arg(feature1));    list.append(QString("%2").arg(faceID2).arg(feature2));    list.append("");    sendData(list.join(""));    emit sendAnaly(clientIP, "请求人脸比对");}void FaceSdkClient::sendAppendFace(const QString &faceID, const QImage &image){    if (!isOk) {        return;    }    QString data = QString("%2").arg(faceID).arg(DeviceFun::getImageData(image));    sendData(data);    emit sendAnaly(clientIP, "添加人脸");}void FaceSdkClient::sendDeleteFace(const QString &faceID){    if (!isOk) {        return;    }    QString data = QString("").arg(faceID);    sendData(data);    emit sendAnaly(clientIP, "删除人脸");}void FaceSdkClient::sendFindByImage(const QString &faceID, const QImage &image){    if (!isOk) {        return;    }    QString data = QString("%2").arg(faceID).arg(DeviceFun::getImageData(image));    sendData(data);    emit sendAnaly(clientIP, "查找最大人脸");}void FaceSdkClient::sendFindByFeature(const QString &faceID, const QString &feature){    if (!isOk) {        return;    }    QString data = QString("%2").arg(faceID).arg(feature);    sendData(data);    emit sendAnaly(clientIP, "查找最大人脸");}

感谢各位的阅读,以上就是"Qt怎么实现人脸识别客户端"的内容了,经过本文的学习后,相信大家对Qt怎么实现人脸识别客户端这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是,小编将为大家推送更多相关知识点的文章,欢迎关注!

0