这篇文章主要介绍“Qt怎么实现人脸识别服务端”,在日常操作中,相信很多人在Qt怎么实现人脸识别服务端问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Qt怎么实现人脸识别服务端”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!
创新互联公司是一家专业提供色尼企业网站建设,专注与成都网站建设、成都网站制作、H5页面制作、小程序制作等业务。10年已为色尼众多企业、政府机构等服务。创新互联专业的建站公司优惠进行中。
一、前言
自定义人脸识别协议采用的是tcp通信协议,其实也可以改成http协议,这也是大部分厂家的做法,毕竟现在http post非常流行,通用性好,返回个json数据非常规范,本程序目前采用的tcp协议是为了兼容以前的旧的系统,毕竟之前的系统都是按照那个格式定义的,推翻重来那之前写过的很多设备的程序都需要更改,一个人肯定忙不过来,而且之前的程序也是经过大量的现场应用检验过的,非常稳定,一旦改动程序的话有需要很长时间的磨合测试。
自定义人脸识别协议功能:
离线使用,同时支持百度的离线包和嵌入式linux人脸识别静态库。
支持多个连接并发,自动排队处理,返回的时候带上唯一标识区分。
传入单张图片返回人脸区域。
传入单张图片返回人脸特征值。
传入单张图片或者多张图片返回是否是活体。
传入两张图片返回比对结果。
传入两个特征值返回比对结果。
传入单张图片添加人脸。
指定唯一标识符删除人脸。
传入单张照片返回相似度最大的人脸信息。
修改人脸服务的配置参数比如是否快速查找、人脸占比等。
二、功能特点
支持的功能包括人脸识别、人脸比对、人脸搜索、活体检测等。
在线版还支持身份证、驾驶证、行驶证、银行卡等识别。
在线版的协议支持百度、旷视,离线版的支持百度,可定制。
除了支持X86架构,还支持嵌入式linux比如contex-A9、树莓派等。
每个功能的执行除了返回结果还返回执行用时时间。
多线程处理,通过type控制当前处理类型。
支持单张图片检索相似度最高的图片。
支持指定目录图片用来生成人脸特征值文件。
可设置等待处理图片队列中的数量。
每次执行都有成功或者失败的信号返回。
人脸搜索的返回结果包含了原图+最大相似度图+相似度等。
人脸比对同时支持两张图片和两个特征值比对。
相关功能自定义一套协议用于客户端和服务端,可以通过TCP通信进行交互。
自定义人脸识别协议非常适用于中心一台服务器,现场若干设备请求的场景。
每个模块全部是独立的一个类,代码整洁、注释完善。
三、效果图
四、核心代码
void FaceSdkSocket::checkData() { QMutexLocker locker(&mutex); QDomDocument dom; if (!DeviceFun::getReceiveXmlData(buffer, dom, "IFACE:", 10)) { return; } //逐个取出节点判断数据 emit receiveData(clientIP, dom.toString()); QDomElement element = dom.documentElement(); if (element.tagName() == "FaceClient") { QString deviceIP = element.attribute("DeviceIP"); QDomNode childNode = element.firstChild(); QString name = childNode.nodeName(); QString value = element.text(); //qDebug() << TIMEMS << name << value; if (name == "DeviceHeart") { sendOk(); emit receiveAnaly(deviceIP, "设备心跳"); } else if (name == "FindFace") { element = childNode.toElement(); value = element.text(); if (value.length() == 0) { return; } //用连接的描述符加上用户传入的描述符组合,方便接收处判断发送给那个连接 QString faceID = element.attribute("FaceID"); QString flag = QString("%1_%2").arg(this->socketDescriptor()).arg(faceID); QImage image = DeviceFun::getImage(value); checkImage(image); emit receiveAnaly(deviceIP, "请求人脸区域"); //发送到人脸识别线程处理 #ifdef facelocal FaceLocalBaiDu::Instance()->setType(0); FaceLocalBaiDu::Instance()->append(flag, image); #elif facearm FaceLocalArm::Instance()->setType(0); FaceLocalArm::Instance()->append(flag, image); #endif } else if (name == "FindFeature") { element = childNode.toElement(); value = element.text(); if (value.length() == 0) { return; } //用连接的描述符加上用户传入的描述符组合,方便接收处判断发送给那个连接 QString faceID = element.attribute("FaceID"); QString flag = QString("%1_%2").arg(this->socketDescriptor()).arg(faceID); QImage image = DeviceFun::getImage(value); checkImage(image); emit receiveAnaly(deviceIP, "请求人脸特征"); //发送到人脸识别线程处理 #ifdef facelocal FaceLocalBaiDu::Instance()->setType(1); FaceLocalBaiDu::Instance()->append(flag, image); #elif facearm FaceLocalArm::Instance()->setType(1); FaceLocalArm::Instance()->append(flag, image); #endif } else if (name == "FindLive") { element = childNode.toElement(); value = element.text(); if (value.length() == 0) { return; } //用连接的描述符加上用户传入的描述符组合,方便接收处判断发送给那个连接 QString faceID = element.attribute("FaceID"); QString flag = QString("%1_%2").arg(this->socketDescriptor()).arg(faceID); QImage image = DeviceFun::getImage(value); checkImage(image); emit receiveAnaly(deviceIP, "请求活体检测"); //发送到人脸识别线程处理 #ifdef facelocal FaceLocalBaiDu::Instance()->setType(5); FaceLocalBaiDu::Instance()->append(flag, image); #endif } else if (name == "CompareByImage") { //取出子节点 QDomNodeList nodeList = childNode.childNodes(); int nodeCount = nodeList.count(); if (nodeCount == 2) { QString faceID1, faceID2; QImage faceImage1, faceImage2; for (int i = 0; i < nodeCount; i++) { childNode = nodeList.at(i); element = childNode.toElement(); name = childNode.nodeName(); value = element.text(); if (name == "FaceImage1") { faceID1 = element.attribute("FaceID"); faceImage1 = DeviceFun::getImage(value); } else if (name == "FaceImage2") { faceID2 = element.attribute("FaceID"); faceImage2 = DeviceFun::getImage(value); } } checkImage(faceImage1); checkImage(faceImage2); QString flag1 = QString("%1_%2").arg(this->socketDescriptor()).arg(faceID1); QString flag2 = QString("%1_%2").arg(this->socketDescriptor()).arg(faceID2); emit receiveAnaly(deviceIP, "请求人脸照片比对"); //发送到人脸识别线程处理 #ifdef facelocal FaceLocalBaiDu::Instance()->setType(2); FaceLocalBaiDu::Instance()->append(flag1 + "|" + flag2, faceImage1, faceImage2); #elif facearm FaceLocalArm::Instance()->setType(2); FaceLocalArm::Instance()->append(flag1 + "|" + flag2, faceImage1, faceImage2); #endif } } else if (name == "CompareByFeature") { element = childNode.toElement(); QString faceID = element.attribute("FaceID"); //取出子节点 QDomNodeList nodeList = childNode.childNodes(); int nodeCount = nodeList.count(); if (nodeCount == 2) { QStringList faceFeature1, faceFeature2; for (int i = 0; i < nodeCount; i++) { childNode = nodeList.at(i); element = childNode.toElement(); name = childNode.nodeName(); value = element.text(); if (name == "FaceFeature1") { faceFeature1 = value.split("|"); } else if (name == "FaceFeature2") { faceFeature2 = value.split("|"); } } emit receiveAnaly(deviceIP, "请求人脸特征比对"); //特征比对速度非常快,忽略不计,立即比对并将结果返回 int count1 = faceFeature1.count(); int count2 = faceFeature2.count(); if (count1 != 256 || count2 != 256) { sendMsg("faceFeature count != 256"); return; } QListfeature1, feature2; for (int i = 0; i < 256; i++) { feature1 << faceFeature1.at(i).toFloat(); feature2 << faceFeature2.at(i).toFloat(); } #ifdef facelocal float result = FaceLocalBaiDu::Instance()->getFaceCompare(faceID, feature1, feature2); sendFaceCompare(faceID, result, 1); #elif facearm float result = FaceLocalArm::Instance()->getFaceCompare(faceID, feature1, feature2); sendFaceCompare(faceID, result, 1); #endif } } else if (name == "AppendFace") { element = childNode.toElement(); value = element.text(); if (value.length() == 0) { return; } //用连接的描述符加上用户传入的描述符组合,方便接收处判断发送给那个连接 QString faceID = element.attribute("FaceID"); QString flag = QString("%1_%2").arg(this->socketDescriptor()).arg(faceID); QImage image = DeviceFun::getImage(value); checkImage(image); emit receiveAnaly(deviceIP, "添加人脸"); //发送到人脸识别线程处理 QString file = QString("%1/%2.txt").arg(FACEPATH).arg(faceID); #ifdef facelocal FaceLocalBaiDu::Instance()->appendFace(flag, image, file); #elif facearm FaceLocalArm::Instance()->appendFace(flag, image, file); #endif } else if (name == "DeleteFace") { element = childNode.toElement(); value = element.text(); if (value.length() == 0) { return; } //用连接的描述符加上用户传入的描述符组合,方便接收处判断发送给那个连接 QString faceID = element.attribute("FaceID"); emit receiveAnaly(deviceIP, "删除人脸"); //发送到人脸识别线程处理 #ifdef facelocal FaceLocalBaiDu::Instance()->deleteFace(faceID); #elif facearm FaceLocalArm::Instance()->deleteFace(faceID); #endif sendOk(); } else if (name == "FindByImage") { element = childNode.toElement(); value = element.text(); if (value.length() == 0) { return; } //用连接的描述符加上用户传入的描述符组合,方便接收处判断发送给那个连接 QString faceID = element.attribute("FaceID"); QString flag = QString("%1_%2").arg(this->socketDescriptor()).arg(faceID); QImage image = DeviceFun::getImage(value); checkImage(image); emit receiveAnaly(deviceIP, "根据图片查找人脸"); //发送到人脸识别线程处理 #ifdef facelocal FaceLocalBaiDu::Instance()->setOneImg(flag, image); #elif facearm FaceLocalArm::Instance()->setOneImg(flag, image); #endif } else if (name == "FindByFeature") { element = childNode.toElement(); value = element.text(); if (value.length() == 0) { return; } //用连接的描述符加上用户传入的描述符组合,方便接收处判断发送给那个连接 QString faceID = element.attribute("FaceID"); QStringList faceFeature = value.split("|"); emit receiveAnaly(deviceIP, "根据特征查找人脸"); int count = faceFeature.count(); if (count != 256) { return; } QList feature; for (int i = 0; i < 256; i++) { feature << faceFeature.at(i).toFloat(); } //比对速度很快,立即比对并返回结果 QString targetName; float result; int msec; #ifdef facelocal FaceLocalBaiDu::Instance()->getFaceOne(faceID, feature, targetName, result, msec); #elif facearm FaceLocalArm::Instance()->getFaceOne(faceID, feature, targetName, result, msec); #endif if (!targetName.isEmpty()) { QString imageFile = QString("%1/%2").arg(FACEPATH).arg(targetName); sendFaceCompareOne(faceID, QImage(), QImage(imageFile), targetName, result, msec); } } else if (name == "UpdateConfig") { element = childNode.toElement(); emit receiveAnaly(deviceIP, "修改人脸配置"); bool findFast = (element.attribute("FindFast") == "true" ? true : false); int facePercent = element.attribute("FacePercent").toInt(); #ifdef facelocal FaceLocalBaiDu::Instance()->setFindFast(findFast); FaceLocalBaiDu::Instance()->setPercent(facePercent); #elif facearm FaceLocalArm::Instance()->setFindFast(findFast); FaceLocalArm::Instance()->setPercent(facePercent); #endif //立即回复 sendFaceConfig(findFast, facePercent); emit configChanged(findFast, facePercent); } } } void FaceSdkSocket::checkImage(const QImage &image) { //如果照片宽高过大则发出提示到客户端 if (image.width() >= 1280 || image.height() >= 720) { sendMsg("Image Size Is Too Large"); } } void FaceSdkSocket::setClientIP(const QString &clientIP) { this->clientIP = clientIP; } QString FaceSdkSocket::getClientIP() { return this->clientIP; } void FaceSdkSocket::sendData(const QString &body) { //构建xml字符串 QStringList list; list.append(QString(" ").arg(clientIP).arg(DATETIME)); list.append(body); list.append(" "); QString data = DeviceFun::getSendXmlData(list.join(""), "IFACE:"); this->write(data.toUtf8()); emit sendData(clientIP, data); } void FaceSdkSocket::sendOk() { sendData(""); emit sendAnaly(clientIP, "心跳应答"); } void FaceSdkSocket::sendMsg(const QString &msg) { sendData(QString("%1 ").arg(msg)); emit sendAnaly(clientIP, "提示信息"); } void FaceSdkSocket::sendFaceRect(const QString &faceID, const QString &faceRect, int msec) { QString data = QString("%2 ") .arg(faceID).arg(faceRect).arg(msec); sendData(data); emit sendAnaly(clientIP, "返回人脸区域"); } void FaceSdkSocket::sendFaceFeature(const QString &faceID, const QString &faceFeature, int msec) { QString data = QString("%2 ") .arg(faceID).arg(faceFeature).arg(msec); sendData(data); emit sendAnaly(clientIP, "返回人脸特征"); } void FaceSdkSocket::sendFaceCompare(const QString &faceID, float result, int msec) { QString data = QString("") .arg(faceID).arg(result).arg(msec); sendData(data); emit sendAnaly(clientIP, "返回人脸比对结果"); } void FaceSdkSocket::sendFaceCompareOne(const QString &faceID, const QImage &sourceImage, const QImage &targetImage, const QString &targetName, float result, int msec) { QString data = QString(" %4|%5 ") .arg(faceID).arg(result).arg(targetName).arg(DeviceFun::getImageData(sourceImage)).arg(DeviceFun::getImageData(targetImage)).arg(msec); sendData(data); emit sendAnaly(clientIP, "返回最相似人脸"); }
到此,关于“Qt怎么实现人脸识别服务端”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注创新互联网站,小编会继续努力为大家带来更多实用的文章!
文章标题:Qt怎么实现人脸识别服务端
本文地址:http://lswzjz.com/article/pdcosg.html