• 14440阅读
  • 28回复

Qt编写人脸识别人脸比对证件识别 [复制链接]

上一主题 下一主题
离线liudianwu
 

图酷模式  只看楼主 倒序阅读 楼主  发表于: 2017-09-17
项目需要,将刷卡抓拍到的图像和身份证图像进行比对,判断出是否为同一人,用opencv或者离线SDK做,效率低识别率低,索性直接用web api,我采用的是face++,据说支付宝刷脸也是用的该公司的库,我测试了下,准确度100%。特意花了两天时间写了个类,将处理封装了下。该类已经集成在QFramework中。返回json数据解析使用QScript解析,没有使用qt5中的json类,因为我的目标运行平台为qt4.8。
运行效果:
window.open('http://www.qtcn.org/bbs/attachment/Mon_1709/44_110085_869210855ba5377.png?201');" style="max-width:700px;max-height:700px;" onload="if(is_ie6&&this.offsetWidth>700)this.width=700;" >





主要功能:
  1. /**
  2. * face++ 证件识别+人脸识别+人脸比对等功能类 作者:feiyangqingyun(QQ:517216493) 2017-9-16
  3. * 1:可识别身份证正面信息+背面信息
  4. * 2:可识别银行卡信息
  5. * 3:可识别驾驶证+行驶证信息
  6. * 4:可进行人脸识别,人脸比对
  7. * 5:可设置请求地址+用户密钥+应用密钥
  8. * 6:直接传入图片即可,信号返回,毫秒级极速响应
  9. * 7:通用Qt4-Qt5,windows linux 嵌入式linux
  10. */

核心代码:
  1. void Face::sendData(const QList<QHttpPart> &parts)
  2. {
  3.     //初始化消息体
  4.     QHttpMultiPart *multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType);
  5.     //添加用户密钥
  6.     QHttpPart keyPart = dataToHttpPart(key.toLatin1(), QVariant("form-data; name=\"api_key\""));
  7.     multiPart->append(keyPart);
  8.     //添加应用密钥
  9.     QHttpPart secretPart = dataToHttpPart(secret.toLatin1(), QVariant("form-data; name=\"api_secret\""));
  10.     multiPart->append(secretPart);
  11.     //逐个添加消息内容
  12.     foreach (QHttpPart part, parts) {
  13.         multiPart->append(part);
  14.     }
  15.     //初始化请求对象
  16.     QNetworkRequest request;
  17.     request.setUrl(QUrl(url));
  18.     //设置openssl签名配置,否则在ARM上会报错
  19.     QSslConfiguration conf = request.sslConfiguration();
  20.     conf.setPeerVerifyMode(QSslSocket::VerifyNone);
  21. #if (QT_VERSION > QT_VERSION_CHECK(5,0,0))
  22.     conf.setProtocol(QSsl::TlsV1_0);
  23. #else
  24.     conf.setProtocol(QSsl::TlsV1);
  25. #endif
  26.     request.setSslConfiguration(conf);
  27.     //发送请求
  28.     QNetworkReply *reply = manager->post(request, multiPart);
  29.     multiPart->setParent(reply);
  30. }
  31. void Face::finished(QNetworkReply *reply)
  32. {
  33.     QString error = reply->errorString();
  34.     if (!error.isEmpty()) {
  35.         emit receiveError(error);
  36.     }
  37.     if (reply->bytesAvailable() > 0 && reply->error() == QNetworkReply::NoError) {
  38.         QString data = reply->readAll();
  39.         reply->deleteLater();
  40.         //发送接收数据信号
  41.         emit receiveData(data);
  42.         //初始化脚本引擎
  43.         QScriptEngine engine;
  44.         //构建解析对象
  45.         QScriptValue script = engine.evaluate("value=" + data);
  46.         //处理时间
  47.         int time_used = script.property("time_used").toInt32();
  48.         emit receiveTimeUsed(time_used);
  49.         //证件识别
  50.         QScriptValue value_cards = script.property("cards");
  51.         if(value_cards.isArray()) {
  52.             int type;
  53.             QString name, gender, id_card_number, birthday, race, address, side;
  54.             QString valid_date, issued_by;
  55.             QString valid_from, issue_date, class_type, license_number, valid_for, version, nationality;
  56.             QString vehicle_type, vin, plate_no, use_character, owner, model, register_date, engine_no;
  57.             //创建迭代器逐个解析具体值
  58.             QScriptValueIterator it(value_cards);
  59.             while (it.hasNext()) {
  60.                 it.next();
  61.                 //证件类型 1-身份证  2-驾驶证  3-行驶证
  62.                 type = it.value().property("type").toInt32();
  63.                 name = it.value().property("name").toString();
  64.                 gender = it.value().property("gender").toString();
  65.                 id_card_number = it.value().property("id_card_number").toString();
  66.                 birthday = it.value().property("birthday").toString();
  67.                 race = it.value().property("race").toString();
  68.                 address = it.value().property("address").toString();
  69.                 side = it.value().property("side").toString();
  70.                 valid_date = it.value().property("valid_date").toString();
  71.                 issued_by = it.value().property("issued_by").toString();
  72.                 valid_from = it.value().property("valid_from").toString();
  73.                 issue_date = it.value().property("issue_date").toString();
  74.                 class_type = it.value().property("class").toString();
  75.                 license_number = it.value().property("license_number").toString();
  76.                 valid_for = it.value().property("valid_for").toString();
  77.                 version = it.value().property("version").toString();
  78.                 nationality = it.value().property("nationality").toString();
  79.                 vehicle_type = it.value().property("vehicle_type").toString();
  80.                 vin = it.value().property("vin").toString();
  81.                 plate_no = it.value().property("plate_no").toString();
  82.                 use_character = it.value().property("use_character").toString();
  83.                 owner = it.value().property("owner").toString();
  84.                 model = it.value().property("model").toString();
  85.                 register_date = it.value().property("register_date").toString();
  86.                 engine_no = it.value().property("engine_no").toString();
  87.                 if (type == 1) {
  88.                     if (side == "front") {
  89.                         emit receiveIDCardInfoFront(name, gender, id_card_number, birthday, race, address);
  90.                     } else if (side == "back") {
  91.                         emit receiveIDCardInfoBack(valid_date, issued_by);
  92.                     }
  93.                 } else if (type == 2) {
  94.                     emit receiveDriverInfo(valid_from, gender, issued_by, issue_date, class_type, license_number,
  95.                                            valid_for, birthday, version, address, nationality, name);
  96.                 } else if (type == 3) {
  97.                     emit receiveRvehicleInfo(issue_date, vehicle_type, issued_by, vin, plate_no, use_character,
  98.                                              address, owner, model, register_date, engine_no);
  99.                 } else {
  100.                     break;
  101.                 }
  102.             }
  103.         }
  104.         //银行卡识别
  105.         QScriptValue value_bank_cards = script.property("bank_cards");
  106.         if(value_bank_cards.isArray()) {
  107.             QString number;
  108.             QPoint left_bottom, right_top, right_bottom, left_top;
  109.             //创建迭代器逐个解析具体值
  110.             QScriptValueIterator it(value_bank_cards);
  111.             while (it.hasNext()) {
  112.                 it.next();
  113.                 number = it.value().property("number").toString();
  114.                 //取出位置区域
  115.                 QScriptValue value_bound = it.value().property("bound");
  116.                 QScriptValue value_left_bottom = value_bound.property("left_bottom");
  117.                 QScriptValue value_right_top = value_bound.property("right_top");
  118.                 QScriptValue value_right_bottom = value_bound.property("right_bottom");
  119.                 QScriptValue value_left_top = value_bound.property("left_top");
  120.                 left_bottom.setY(value_left_bottom.property("y").toInt32());
  121.                 left_bottom.setX(value_left_bottom.property("x").toInt32());
  122.                 right_top.setY(value_right_top.property("y").toInt32());
  123.                 right_top.setX(value_right_top.property("x").toInt32());
  124.                 right_bottom.setY(value_right_bottom.property("y").toInt32());
  125.                 right_bottom.setX(value_right_bottom.property("x").toInt32());
  126.                 left_top.setY(value_left_top.property("y").toInt32());
  127.                 left_top.setX(value_left_top.property("x").toInt32());
  128.                 if (!number.isEmpty()) {
  129.                     emit receiveBankCardInfo(number, left_bottom, right_top, right_bottom, left_top);
  130.                 } else {
  131.                     break;
  132.                 }
  133.             }
  134.         }
  135.         //人脸识别
  136.         QScriptValue value_faces = script.property("faces");
  137.         if(value_faces.isArray()) {
  138.             QRect face_rectangle;
  139.             //创建迭代器逐个解析具体值
  140.             QScriptValueIterator it(value_faces);
  141.             while (it.hasNext()) {
  142.                 it.next();
  143.                 QScriptValue value_face_rectangle = it.value().property("face_rectangle");
  144.                 face_rectangle.setX(value_face_rectangle.property("left").toInt32());
  145.                 face_rectangle.setY(value_face_rectangle.property("top").toInt32());
  146.                 face_rectangle.setWidth(value_face_rectangle.property("width").toInt32());
  147.                 face_rectangle.setHeight(value_face_rectangle.property("height").toInt32());
  148.                 if (face_rectangle.width() > 0) {
  149.                     emit receiveFaceRect(face_rectangle);
  150.                 } else {
  151.                     break;
  152.                 }
  153.             }
  154.         }
  155.         //人脸比对
  156.         QScriptValue value_faces1 = script.property("faces1");
  157.         QScriptValue value_faces2 = script.property("faces2");
  158.         QRect face1_rectangle, face2_rectangle;
  159.         double confidence = script.property("confidence").toString().toDouble();
  160.         if(value_faces1.isArray()) {
  161.             //创建迭代器逐个解析具体值
  162.             QScriptValueIterator it(value_faces1);
  163.             while (it.hasNext()) {
  164.                 it.next();
  165.                 QScriptValue value_face_rectangle = it.value().property("face_rectangle");
  166.                 face1_rectangle.setX(value_face_rectangle.property("left").toInt32());
  167.                 face1_rectangle.setY(value_face_rectangle.property("top").toInt32());
  168.                 face1_rectangle.setWidth(value_face_rectangle.property("width").toInt32());
  169.                 face1_rectangle.setHeight(value_face_rectangle.property("height").toInt32());
  170.                 if (face1_rectangle.width() <= 0) {
  171.                     break;
  172.                 }
  173.             }
  174.         }
  175.         if(value_faces2.isArray()) {
  176.             //创建迭代器逐个解析具体值
  177.             QScriptValueIterator it(value_faces2);
  178.             while (it.hasNext()) {
  179.                 it.next();
  180.                 QScriptValue value_face_rectangle = it.value().property("face_rectangle");
  181.                 face2_rectangle.setX(value_face_rectangle.property("left").toInt32());
  182.                 face2_rectangle.setY(value_face_rectangle.property("top").toInt32());
  183.                 face2_rectangle.setWidth(value_face_rectangle.property("width").toInt32());
  184.                 face2_rectangle.setHeight(value_face_rectangle.property("height").toInt32());
  185.                 if (face2_rectangle.width() <= 0) {
  186.                     break;
  187.                 }
  188.             }
  189.         }
  190.         if (confidence > 0) {
  191.             emit receiveFaceCompare(face1_rectangle, face2_rectangle, confidence);
  192.         }
  193.     }
  194. }


欢迎关注微信公众号:Qt实战 (各种开源作品、经验整理、项目实战技巧,专注Qt/C++软件开发,视频监控、物联网、工业控制、嵌入式软件、国产化系统应用软件开发)QQ:517216493  WX:feiyangqingyun  QQ群:751439350
离线liudianwu

只看该作者 1楼 发表于: 2017-09-17


欢迎关注微信公众号:Qt实战 (各种开源作品、经验整理、项目实战技巧,专注Qt/C++软件开发,视频监控、物联网、工业控制、嵌入式软件、国产化系统应用软件开发)QQ:517216493  WX:feiyangqingyun  QQ群:751439350
离线仗剑天涯

只看该作者 2楼 发表于: 2017-09-17
    

只看该作者 3楼 发表于: 2017-09-18
求分享代码
离线九重水

只看该作者 4楼 发表于: 2017-09-18
这个做演示例子的‘女子’很有意思
离线liuchangyin

只看该作者 5楼 发表于: 2017-09-18
离线renzhihe

只看该作者 6楼 发表于: 2017-09-18
opencv、?
离线robinsonsir

只看该作者 7楼 发表于: 2017-09-18
离线richards

只看该作者 8楼 发表于: 2017-09-18
   人脸识别我用opencv做过 不过准确度有点低
离线theotherone

只看该作者 9楼 发表于: 2017-09-19
暴露年龄了
屌丝程序猿,努力更屌丝  
博客:http://fearlazy.com
离线z_墨脱

只看该作者 10楼 发表于: 2017-09-19
真的厉害
离线crazy

只看该作者 11楼 发表于: 2017-09-19
顶一顶
C/C++/Qt爱好者
邮箱: kevinlq0912@163.com
公众号: devstone
博客:http://kevinlq.com/
离线xdh873939316

只看该作者 12楼 发表于: 2017-09-21
楼主,厉害,顶起来
离线anber

只看该作者 13楼 发表于: 2017-10-09
离线kettong

只看该作者 14楼 发表于: 2017-10-10
离线wmx菜鸟

只看该作者 15楼 发表于: 2017-10-10
  
离线kaikai_king

只看该作者 16楼 发表于: 2017-10-15
好厉害
离线gfanny

只看该作者 17楼 发表于: 2017-11-14
这是调用了face++接口
离线foxgod

只看该作者 18楼 发表于: 2017-11-15
回 liudianwu 的帖子
liudianwu:[图片]
[图片]
[图片] (2017-09-17 14:09) 

发送数据那个代码,可以详细点吗?
离线foxgod

只看该作者 19楼 发表于: 2017-11-20
你QQ都写错了,我都找错人了,楼主请检查,还有发送http请求的核心代码,可以说下吗,不能抓包看
离线_winterhorse

只看该作者 20楼 发表于: 2018-01-29
      
离线foxgod

只看该作者 21楼 发表于: 2018-04-23
回 liudianwu 的帖子
liudianwu:[图片]
[图片]
[图片] (2017-09-17 14:09) 

这是线上是别的,有离线识别的没
离线liudianwu

只看该作者 22楼 发表于: 2018-04-23
最新的对应应用界面,使用嵌入式linux离线版本。运行在imx6+树莓派+香橙派+全志H3等板上。
欢迎关注微信公众号:Qt实战 (各种开源作品、经验整理、项目实战技巧,专注Qt/C++软件开发,视频监控、物联网、工业控制、嵌入式软件、国产化系统应用软件开发)QQ:517216493  WX:feiyangqingyun  QQ群:751439350
离线nikoladi

只看该作者 23楼 发表于: 2018-04-23
回 liudianwu 的帖子
liudianwu:最新的对应应用界面,使用嵌入式linux离线版本。运行在imx6+树莓派+香橙派+全志H3等板上。
[图片] (2018-04-23 20:28) 

大侠,离线版用的opencv嘛,识别成功率怎么样?
离线dong3936533

只看该作者 24楼 发表于: 2018-04-25
牛逼,
奋斗的菜鸟
离线tramidu

只看该作者 25楼 发表于: 2018-07-27
回 liudianwu 的帖子
liudianwu:最新的对应应用界面,使用嵌入式linux离线版本。运行在imx6+树莓派+香橙派+全志H3等板上。
[图片] (2018-04-23 20:28) 

大神,离线版本的是用opencv来做的吗?有用树莓派来测试过吗?
离线yuefy520

只看该作者 26楼 发表于: 2018-08-03
膜拜,大神啊,跟你混了
离线fight傲

只看该作者 27楼 发表于: 2018-10-25
mark,膜拜刘神
离线qq147735456

只看该作者 28楼 发表于: 2019-12-30
有开源没, 大神.
快速回复
限100 字节
 
上一个 下一个