-
UID:110085
-
- 注册时间2010-12-21
- 最后登录2024-04-26
- 在线时间3538小时
-
- 发帖2742
- 搜Ta的帖子
- 精华2
- 金钱32733
- 威望3371
- 贡献值589
- 好评度3389
-
访问TA的空间加好友用道具
|
AI技术的发展在最近几年如火如荼,工资待遇也是水涨船高,应用的前景也是非常广阔,去年火起来的人脸识别,今年全国遍地开花,之前封装了下face++的人脸识别等接口,今年看了下百度的AI,还免费了,效果也是越来越好,活体检测这个算法更是做的吊炸天(只需要传一张 图片就能判断图片中的人是翻拍的照片非活体),牛逼的一塌糊涂,我反正是跪了。特意花了半天时间将百度人脸识别+图像识别封装了下,以便后期使用。顺便预测下,百度AI在未来的国内AI市场中,不是第一就是第二,而且会持续保持至少十年。 为了兼容qt4,特意采用了qtscript解析收到的 数据。 * 1:可识别身份证正面信息+背面信息 * 2:可识别银行卡信息 * 3:可识别驾驶证+行驶证信息 * 4:可进行人脸识别,人脸比对,活体检测 * 5:可设置请求地址+用户密钥+应用密钥 * 6:直接传入图片即可,信号返回,毫秒级极速响应 * 7:通用Qt4-Qt5,windows linux 嵌入式linux 可 执行文件下载: https://pan.baidu.com/s/1pzhQL_YMYZyn4hW94e0QsQ window.open('http://www.qtcn.org/bbs/attachment/Mon_1808/44_110085_7977beb03cc72e0.jpg?89');" style="max-width:700px;max-height:700px;" onload="if(is_ie6&&this.offsetWidth>700)this.width=700;" > 核心代码: - QByteArray FaceBaiDu::getImageData(const QImage &img)
- {
- QImage image = img;
- QByteArray imageData;
- QBuffer buffer(&imageData);
- image.save(&buffer, "jpg");
- return imageData.toBase64();
- }
- QString FaceBaiDu::getImageData2(const QImage &img)
- {
- return QString(getImageData(img));
- }
- QHttpPart FaceBaiDu::dataToHttpPart(const QByteArray &body, const QString &name)
- {
- QHttpPart httpPart;
- httpPart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant(QString("form-data;name=\"%1\"").arg(name)));
- httpPart.setBody(body);
- return httpPart;
- }
- void FaceBaiDu::sendData(const QString &url, const QList<QHttpPart> &httpParts)
- {
- //初始化消息体
- QHttpMultiPart *httpMultiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType);
- //逐个添加消息内容
- foreach (QHttpPart httpPart, httpParts) {
- httpMultiPart->append(httpPart);
- }
- //初始化请求对象
- QNetworkRequest request;
- request.setUrl(QUrl(url));
- #ifdef ssl
- //设置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);
- #endif
- //发送请求
- QNetworkReply *reply = manager->post(request, httpMultiPart);
- httpMultiPart->setParent(reply);
- }
- void FaceBaiDu::finished(QNetworkReply *reply)
- {
- QString error = reply->errorString();
- if (!error.isEmpty() && error != "Unknown error") {
- 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);
- //获取鉴权标识符
- QString token = script.property("access_token").toString();
- if (!token.isEmpty()) {
- tokenFace = token;
- tokenOcr = token;
- }
- //通用返回结果字段
- int code = script.property("error_code").toInt32();
- QString msg = script.property("error_msg").toString();
- emit receiveResult(code, msg);
- //人脸识别部分
- QScriptValue result = script.property("result");
- if (!result.isNull()) {
- //人脸识别
- QScriptValue face_list = result.property("face_list");
- if (face_list.isObject()) {
- checkFaceList(face_list);
- }
- //人脸比对
- QScriptValue score = result.property("score");
- if (!score.isNull()) {
- double value = score.toString().toDouble();
- if (value > 0) {
- emit receiveFaceCompare(QRect(), QRect(), value);
- } else {
- emit receiveFaceCompareFail();
- }
- }
- //活体检测
- QScriptValue face_liveness = result.property("face_liveness");
- if (!face_liveness.isNull()) {
- double liveness = face_liveness.toString().toDouble();
- if (liveness > 0) {
- emit receiveLive(liveness);
- }
- }
- //银行卡
- QScriptValue bank_card_number = result.property("bank_card_number");
- if (!bank_card_number.isNull()) {
- QString card_number = bank_card_number.toString();
- QString bank_name = result.property("bank_name").toString();
- if (!card_number.isEmpty()) {
- emit receiveBankCardInfo(card_number, bank_name);
- }
- }
- }
- //文字识别部分
- QScriptValue words_result = script.property("words_result");
- if (!words_result.isNull()) {
- //身份证正面
- QScriptValue nation = words_result.property("民族");
- if (nation.isObject()) {
- checkCardFront(words_result);
- }
- //身份证反面
- QScriptValue issuedby = words_result.property("签发机关");
- if (issuedby.isObject()) {
- checkCardBack(words_result);
- }
- //驾驶证
- QScriptValue license_number = words_result.property("证号");
- if (license_number.isObject()) {
- checkDriverLicense(words_result);
- }
- //行驶证
- QScriptValue model = words_result.property("品牌型号");
- if (model.isObject()) {
- checkRVehicleLicense(words_result);
- }
- }
- }
- }
- void FaceBaiDu::checkFaceList(const QScriptValue &face_list)
- {
- QRect face_rectangle;
- //创建迭代器逐个解析具体值
- QScriptValueIterator it(face_list);
- while (it.hasNext()) {
- it.next();
- QString face_token = it.value().property("face_token").toString();
- if (!face_token.isEmpty()) {
- QScriptValue location = it.value().property("location");
- if (location.isObject()) {
- face_rectangle.setX(location.property("left").toInt32());
- face_rectangle.setY(location.property("top").toInt32());
- face_rectangle.setWidth(location.property("width").toInt32());
- face_rectangle.setHeight(location.property("height").toInt32());
- }
- }
- it.next();
- if (face_rectangle.width() > 0) {
- emit receiveFaceRect(face_rectangle);
- } else {
- break;
- }
- }
- }
- void FaceBaiDu::checkCardFront(const QScriptValue &scriptValue)
- {
- QScriptValue name = scriptValue.property("姓名");
- QScriptValue address = scriptValue.property("住址");
- QScriptValue birthday = scriptValue.property("出生");
- QScriptValue number = scriptValue.property("公民身份号码");
- QScriptValue sex = scriptValue.property("性别");
- QScriptValue nation = scriptValue.property("民族");
- QString strName = name.property("words").toString();
- QString strAddress = address.property("words").toString();
- QString strBirthday = birthday.property("words").toString();
- QString strNumber = number.property("words").toString();
- QString strSex = sex.property("words").toString();
- QString strNation = nation.property("words").toString();
- emit receiveIDCardInfoFront(strName, strSex, strNumber, strBirthday, strNation, strAddress);
- }
- void FaceBaiDu::checkCardBack(const QScriptValue &scriptValue)
- {
- QScriptValue issuedby = scriptValue.property("签发机关");
- QScriptValue dateStart = scriptValue.property("签发日期");
- QScriptValue dateEnd = scriptValue.property("失效日期");
- QString strIssuedby = issuedby.property("words").toString();
- QString strDataStart = dateStart.property("words").toString();
- QString strDateEnd = dateEnd.property("words").toString();
- QString strDate = QString("%1.%2.%3-%4.%5.%6")
- .arg(strDataStart.mid(0, 4)).arg(strDataStart.mid(4, 2)).arg(strDataStart.mid(6, 2))
- .arg(strDateEnd.mid(0, 4)).arg(strDateEnd.mid(4, 2)).arg(strDateEnd.mid(6, 2));
- emit receiveIDCardInfoBack(strDate, strIssuedby);
- }
- void FaceBaiDu::checkDriverLicense(const QScriptValue &scriptValue)
- {
- QScriptValue licenseNumber = scriptValue.property("证号");
- QScriptValue name = scriptValue.property("姓名");
- QScriptValue gender = scriptValue.property("性别");
- QScriptValue nationality = scriptValue.property("国籍");
- QScriptValue address = scriptValue.property("住址");
- QScriptValue birthday = scriptValue.property("出生日期");
- QScriptValue issueDate = scriptValue.property("初次领证日期");
- QScriptValue classType = scriptValue.property("准驾车型");
- QScriptValue validFrom = scriptValue.property("有效起始日期");
- QScriptValue validFor = scriptValue.property("有效期限");
- QString strLicenseNumber = licenseNumber.property("words").toString();
- QString strName = name.property("words").toString();
- QString strGender = gender.property("words").toString();
- QString strNationality = nationality.property("words").toString();
- QString strAddress = address.property("words").toString();
- QString strBirthday = birthday.property("words").toString();
- QString strIssueDate = issueDate.property("words").toString();
- QString strClassType = classType.property("words").toString();
- QString strValidFrom = validFrom.property("words").toString();
- QString strValidFor = validFor.property("words").toString();
- emit receiveDriverInfo(strValidFrom, strGender, "", strIssueDate, strClassType, strLicenseNumber,
- strValidFor, strBirthday, "1", strAddress, strNationality, strName);
- }
- void FaceBaiDu::checkRVehicleLicense(const QScriptValue &scriptValue)
- {
- QScriptValue plateNo = scriptValue.property("号牌号码");
- QScriptValue vehicleType = scriptValue.property("车辆类型");
- QScriptValue owner = scriptValue.property("所有人");
- QScriptValue address = scriptValue.property("住址");
- QScriptValue useCharacter = scriptValue.property("使用性质");
- QScriptValue model = scriptValue.property("品牌型号");
- QScriptValue vin = scriptValue.property("车辆识别代号");
- QScriptValue engineNo = scriptValue.property("发动机号码");
- QScriptValue registerDate = scriptValue.property("注册日期");
- QScriptValue issueDate = scriptValue.property("发证日期");
- QString strPlateNo = plateNo.property("words").toString();
- QString strCehicleType = vehicleType.property("words").toString();
- QString strOwner = owner.property("words").toString();
- QString strAddress = address.property("words").toString();
- QString strUseCharacter = useCharacter.property("words").toString();
- QString strModel = model.property("words").toString();
- QString strVin = vin.property("words").toString();
- QString strEngineNo = engineNo.property("words").toString();
- QString strRegisterDate = registerDate.property("words").toString();
- QString strIssueDate = issueDate.property("words").toString();
- emit receiveRvehicleInfo(strIssueDate, strCehicleType, "", strVin, strPlateNo, strUseCharacter,
- strAddress, strOwner, strModel, strRegisterDate, strEngineNo);
- }
- void FaceBaiDu::sendData(const QString &url, const QString &data, const QString &header)
- {
- QNetworkRequest request;
- request.setHeader(QNetworkRequest::ContentTypeHeader, header);
- request.setUrl(QUrl(url));
- #ifdef ssl
- //设置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);
- #endif
- manager->post(request, data.toUtf8());
- }
- void FaceBaiDu::getToken(const QString &client_id, const QString &client_secret)
- {
- QStringList list;
- list.append(QString("grant_type=%1").arg("client_credentials"));
- list.append(QString("client_id=%1").arg(client_id));
- list.append(QString("client_secret=%1").arg(client_secret));
- QString data = list.join("&");
- QString url = "https://aip.baidubce.com/oauth/2.0/token";
- sendData(url, data);
- }
- void FaceBaiDu::detect(const QImage &img)
- {
- QStringList list;
- list.append(QString("{\"image\":\"%1\",\"image_type\":\"BASE64\"}").arg(getImageData2(img)));
- QString data = list.join("");
- QString url = QString("https://aip.baidubce.com/rest/2.0/face/v3/detect?access_token=%1").arg(tokenFace);
- sendData(url, data);
- }
- void FaceBaiDu::compare(const QImage &img1, const QImage &img2)
- {
- QString imgData1 = getImageData2(img1);
- QString imgData2 = getImageData2(img2);
- //如果需要活体检测则NONE改为LOW NORMAL HIGH
- QStringList list;
- list.append("[");
- list.append(QString("{\"image\":\"%1\",\"image_type\":\"BASE64\",\"liveness_control\":\"NONE\"}").arg(imgData1));
- list.append(",");
- list.append(QString("{\"image\":\"%1\",\"image_type\":\"BASE64\",\"liveness_control\":\"NONE\"}").arg(imgData2));
- list.append("]");
- QString data = list.join("");
- QString url = QString("https://aip.baidubce.com/rest/2.0/face/v3/match?access_token=%1").arg(tokenFace);
- sendData(url, data);
- }
- void FaceBaiDu::live(const QImage &img)
- {
- QList<QImage> imgs;
- if (!img.isNull()) {
- imgs << img;
- }
- live(imgs);
- }
- void FaceBaiDu::live(const QList<QImage> &imgs)
- {
- //记住最后一次处理的时间,限制频繁的调用
- QDateTime now = QDateTime::currentDateTime();
- if (lastTime.msecsTo(now) < 500) {
- return;
- }
- lastTime = now;
- QStringList list;
- list.append("[");
- int count = imgs.count();
- for (int i = 0; i < count; i++) {
- QString imgData = getImageData2(imgs.at(i));
- list.append(QString("{\"image\":\"%1\",\"image_type\":\"BASE64\"}").arg(imgData));
- if (i < count - 1) {
- list.append(",");
- }
- }
- list.append("]");
- QString data = list.join("");
- QString url = QString("https://aip.baidubce.com/rest/2.0/face/v3/faceverify?access_token=%1").arg(tokenFace);
- sendData(url, data);
- }
- void FaceBaiDu::idmatch(const QString &idcard, const QString &name)
- {
- QStringList list;
- list.append(QString("{\"id_card_num\":\"%1\",\"name\":\"%2\"}").arg(idcard).arg(name));
- QString data = list.join("");
- QString url = QString("https://aip.baidubce.com/rest/2.0/face/v3/person/idmatch?access_token=%1").arg(tokenFace);
- sendData(url, data);
- }
- void FaceBaiDu::idcard(const QImage &img, bool front)
- {
- QList<QHttpPart> httpParts;
- httpParts << dataToHttpPart(front ? "front" : "back", "id_card_side");
- httpParts << dataToHttpPart(getImageData(img), "image");
- QString url = QString("https://aip.baidubce.com/rest/2.0/ocr/v1/idcard?access_token=%1").arg(tokenOcr);
- sendData(url, httpParts);
- }
- void FaceBaiDu::bankcard(const QImage &img)
- {
- QList<QHttpPart> httpParts;
- httpParts << dataToHttpPart(getImageData(img), "image");
- QString url = QString("https://aip.baidubce.com/rest/2.0/ocr/v1/bankcard?access_token=%1").arg(tokenOcr);
- sendData(url, httpParts);
- }
- void FaceBaiDu::driverLicense(const QImage &img)
- {
- QList<QHttpPart> httpParts;
- httpParts << dataToHttpPart(getImageData(img), "image");
- QString url = QString("https://aip.baidubce.com/rest/2.0/ocr/v1/driving_license?access_token=%1").arg(tokenOcr);
- sendData(url, httpParts);
- }
- void FaceBaiDu::vehicleLicense(const QImage &img)
- {
- QList<QHttpPart> httpParts;
- httpParts << dataToHttpPart(getImageData(img), "image");
- QString url = QString("https://aip.baidubce.com/rest/2.0/ocr/v1/vehicle_license?access_token=%1").arg(tokenOcr);
- sendData(url, httpParts);
- }
|