查看完整版本: [-- Qt编写人脸识别人脸比对证件识别 --]

QTCN开发网 -> Qt 作品展 -> Qt编写人脸识别人脸比对证件识别 [打印本页] 登录 -> 注册 -> 回复主题 -> 发表主题

liudianwu 2017-09-17 14:04

Qt编写人脸识别人脸比对证件识别

项目需要,将刷卡抓拍到的图像和身份证图像进行比对,判断出是否为同一人,用opencv或者离线SDK做,效率低识别率低,索性直接用web api,我采用的是face++,据说支付宝刷脸也是用的该公司的库,我测试了下,准确度100%。特意花了两天时间写了个类,将处理封装了下。该类已经集成在QFramework中。返回json数据解析使用QScript解析,没有使用qt5中的json类,因为我的目标运行平台为qt4.8。
运行效果:
[attachment=17913]
[attachment=17914]
[attachment=17915]
[attachment=17916]
[attachment=17917]

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

核心代码:
  1. void Face::sendData(const QList<QHttpPart> &parts)
    {
        //初始化消息体
        QHttpMultiPart *multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType);

        //添加用户密钥
        QHttpPart keyPart = dataToHttpPart(key.toLatin1(), QVariant("form-data; name=\"api_key\""));
        multiPart->append(keyPart);

        //添加应用密钥
        QHttpPart secretPart = dataToHttpPart(secret.toLatin1(), QVariant("form-data; name=\"api_secret\""));
        multiPart->append(secretPart);

        //逐个添加消息内容
        foreach (QHttpPart part, parts) {
            multiPart->append(part);
        }

        //初始化请求对象
        QNetworkRequest request;
        request.setUrl(QUrl(url));

        //设置openssl签名配置,否则在ARM上会报错
        QSslConfiguration conf = request.sslConfiguration();
        conf.setPeerVerifyMode(QSslSocket::VerifyNone);
    #if (QT_VERSION > QT_VERSION_CHECK(5,0,0))
        conf.setProtocol(QSsl::TlsV1_0);
    #else
        conf.setProtocol(QSsl::TlsV1);
    #endif
        request.setSslConfiguration(conf);

        //发送请求
        QNetworkReply *reply = manager->post(request, multiPart);
        multiPart->setParent(reply);
    }

    void Face::finished(QNetworkReply *reply)
    {
        QString error = reply->errorString();
        if (!error.isEmpty()) {
            emit receiveError(error);
        }

        if (reply->bytesAvailable() > 0 && reply->error() == QNetworkReply::NoError) {
            QString data = reply->readAll();
            reply->deleteLater();

            //发送接收数据信号
            emit receiveData(data);

            //初始化脚本引擎
            QScriptEngine engine;
            //构建解析对象
            QScriptValue script = engine.evaluate("value=" + data);

            //处理时间
            int time_used = script.property("time_used").toInt32();
            emit receiveTimeUsed(time_used);

            //证件识别
            QScriptValue value_cards = script.property("cards");
            if(value_cards.isArray()) {
                int type;
                QString name, gender, id_card_number, birthday, race, address, side;
                QString valid_date, issued_by;
                QString valid_from, issue_date, class_type, license_number, valid_for, version, nationality;
                QString vehicle_type, vin, plate_no, use_character, owner, model, register_date, engine_no;

                //创建迭代器逐个解析具体值
                QScriptValueIterator it(value_cards);
                while (it.hasNext()) {
                    it.next();

                    //证件类型 1-身份证  2-驾驶证  3-行驶证
                    type = it.value().property("type").toInt32();

                    name = it.value().property("name").toString();
                    gender = it.value().property("gender").toString();
                    id_card_number = it.value().property("id_card_number").toString();
                    birthday = it.value().property("birthday").toString();
                    race = it.value().property("race").toString();
                    address = it.value().property("address").toString();
                    side = it.value().property("side").toString();

                    valid_date = it.value().property("valid_date").toString();
                    issued_by = it.value().property("issued_by").toString();

                    valid_from = it.value().property("valid_from").toString();
                    issue_date = it.value().property("issue_date").toString();
                    class_type = it.value().property("class").toString();
                    license_number = it.value().property("license_number").toString();
                    valid_for = it.value().property("valid_for").toString();
                    version = it.value().property("version").toString();
                    nationality = it.value().property("nationality").toString();

                    vehicle_type = it.value().property("vehicle_type").toString();
                    vin = it.value().property("vin").toString();
                    plate_no = it.value().property("plate_no").toString();
                    use_character = it.value().property("use_character").toString();
                    owner = it.value().property("owner").toString();
                    model = it.value().property("model").toString();
                    register_date = it.value().property("register_date").toString();
                    engine_no = it.value().property("engine_no").toString();

                    if (type == 1) {
                        if (side == "front") {
                            emit receiveIDCardInfoFront(name, gender, id_card_number, birthday, race, address);
                        } else if (side == "back") {
                            emit receiveIDCardInfoBack(valid_date, issued_by);
                        }
                    } else if (type == 2) {
                        emit receiveDriverInfo(valid_from, gender, issued_by, issue_date, class_type, license_number,
                                               valid_for, birthday, version, address, nationality, name);
                    } else if (type == 3) {
                        emit receiveRvehicleInfo(issue_date, vehicle_type, issued_by, vin, plate_no, use_character,
                                                 address, owner, model, register_date, engine_no);
                    } else {
                        break;
                    }
                }
            }

            //银行卡识别
            QScriptValue value_bank_cards = script.property("bank_cards");
            if(value_bank_cards.isArray()) {
                QString number;
                QPoint left_bottom, right_top, right_bottom, left_top;

                //创建迭代器逐个解析具体值
                QScriptValueIterator it(value_bank_cards);
                while (it.hasNext()) {
                    it.next();

                    number = it.value().property("number").toString();

                    //取出位置区域
                    QScriptValue value_bound = it.value().property("bound");
                    QScriptValue value_left_bottom = value_bound.property("left_bottom");
                    QScriptValue value_right_top = value_bound.property("right_top");
                    QScriptValue value_right_bottom = value_bound.property("right_bottom");
                    QScriptValue value_left_top = value_bound.property("left_top");

                    left_bottom.setY(value_left_bottom.property("y").toInt32());
                    left_bottom.setX(value_left_bottom.property("x").toInt32());

                    right_top.setY(value_right_top.property("y").toInt32());
                    right_top.setX(value_right_top.property("x").toInt32());

                    right_bottom.setY(value_right_bottom.property("y").toInt32());
                    right_bottom.setX(value_right_bottom.property("x").toInt32());

                    left_top.setY(value_left_top.property("y").toInt32());
                    left_top.setX(value_left_top.property("x").toInt32());

                    if (!number.isEmpty()) {
                        emit receiveBankCardInfo(number, left_bottom, right_top, right_bottom, left_top);
                    } else {
                        break;
                    }
                }
            }

            //人脸识别
            QScriptValue value_faces = script.property("faces");
            if(value_faces.isArray()) {
                QRect face_rectangle;

                //创建迭代器逐个解析具体值
                QScriptValueIterator it(value_faces);
                while (it.hasNext()) {
                    it.next();

                    QScriptValue value_face_rectangle = it.value().property("face_rectangle");
                    face_rectangle.setX(value_face_rectangle.property("left").toInt32());
                    face_rectangle.setY(value_face_rectangle.property("top").toInt32());
                    face_rectangle.setWidth(value_face_rectangle.property("width").toInt32());
                    face_rectangle.setHeight(value_face_rectangle.property("height").toInt32());

                    if (face_rectangle.width() > 0) {
                        emit receiveFaceRect(face_rectangle);
                    } else {
                        break;
                    }
                }
            }

            //人脸比对
            QScriptValue value_faces1 = script.property("faces1");
            QScriptValue value_faces2 = script.property("faces2");
            QRect face1_rectangle, face2_rectangle;
            double confidence = script.property("confidence").toString().toDouble();

            if(value_faces1.isArray()) {
                //创建迭代器逐个解析具体值
                QScriptValueIterator it(value_faces1);
                while (it.hasNext()) {
                    it.next();

                    QScriptValue value_face_rectangle = it.value().property("face_rectangle");
                    face1_rectangle.setX(value_face_rectangle.property("left").toInt32());
                    face1_rectangle.setY(value_face_rectangle.property("top").toInt32());
                    face1_rectangle.setWidth(value_face_rectangle.property("width").toInt32());
                    face1_rectangle.setHeight(value_face_rectangle.property("height").toInt32());

                    if (face1_rectangle.width() <= 0) {
                        break;
                    }
                }
            }

            if(value_faces2.isArray()) {
                //创建迭代器逐个解析具体值
                QScriptValueIterator it(value_faces2);
                while (it.hasNext()) {
                    it.next();

                    QScriptValue value_face_rectangle = it.value().property("face_rectangle");
                    face2_rectangle.setX(value_face_rectangle.property("left").toInt32());
                    face2_rectangle.setY(value_face_rectangle.property("top").toInt32());
                    face2_rectangle.setWidth(value_face_rectangle.property("width").toInt32());
                    face2_rectangle.setHeight(value_face_rectangle.property("height").toInt32());

                    if (face2_rectangle.width() <= 0) {
                        break;
                    }
                }
            }

            if (confidence > 0) {
                emit receiveFaceCompare(face1_rectangle, face2_rectangle, confidence);
            }
        }
    }



liudianwu 2017-09-17 14:09
[attachment=17918]
[attachment=17919]
[attachment=17920]

仗剑天涯 2017-09-17 14:41
    

青春的年代 2017-09-18 08:18
求分享代码

九重水 2017-09-18 08:40
这个做演示例子的‘女子’很有意思

liuchangyin 2017-09-18 10:40

renzhihe 2017-09-18 16:34
opencv、?

robinsonsir 2017-09-18 17:42

richards 2017-09-18 19:09
   人脸识别我用opencv做过 不过准确度有点低

theotherone 2017-09-19 08:46
暴露年龄了

z_墨脱 2017-09-19 14:27
真的厉害

crazy 2017-09-19 19:25
顶一顶

xdh873939316 2017-09-21 10:48
楼主,厉害,顶起来

anber 2017-10-09 17:07

kettong 2017-10-10 10:05

wmx菜鸟 2017-10-10 10:12
  

kaikai_king 2017-10-15 15:57
好厉害

gfanny 2017-11-14 10:30
这是调用了face++接口

foxgod 2017-11-15 17:45
liudianwu:[图片]
[图片]
[图片] (2017-09-17 14:09) 

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

foxgod 2017-11-20 16:02
你QQ都写错了,我都找错人了,楼主请检查,还有发送http请求的核心代码,可以说下吗,不能抓包看

_winterhorse 2018-01-29 10:22
      

foxgod 2018-04-23 16:14
liudianwu:[图片]
[图片]
[图片] (2017-09-17 14:09) 

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

liudianwu 2018-04-23 20:28
最新的对应应用界面,使用嵌入式linux离线版本。运行在imx6+树莓派+香橙派+全志H3等板上。
[attachment=18785]

nikoladi 2018-04-23 23:50
liudianwu:最新的对应应用界面,使用嵌入式linux离线版本。运行在imx6+树莓派+香橙派+全志H3等板上。
[图片] (2018-04-23 20:28) 

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

dong3936533 2018-04-25 17:14
牛逼,

tramidu 2018-07-27 20:42
liudianwu:最新的对应应用界面,使用嵌入式linux离线版本。运行在imx6+树莓派+香橙派+全志H3等板上。
[图片] (2018-04-23 20:28) 

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

yuefy520 2018-08-03 18:29
膜拜,大神啊,跟你混了

fight傲 2018-10-25 14:30
mark,膜拜刘神

qq147735456 2019-12-30 16:51
有开源没, 大神.


查看完整版本: [-- Qt编写人脸识别人脸比对证件识别 --] [-- top --]



Powered by phpwind v8.7 Code ©2003-2011 phpwind
Gzip disabled