AI人脸识别+图像识别【文末源码分享】
AI的发展在最近几年如火如荼,工资待遇也是水涨船高,应用的前景也是非常广阔,去年火起来的人脸识别,今年全国遍地开花。看了下百度的AI,还免费了,效果也是越来越好,活体检测这个算法更是做的吊炸天(只需要传一张图片就能判断图片中的人是翻拍的照片非活体),牛逼的一塌糊涂,我反正是跪了。百度AI在未来的国内AI市场中,不是第一就是第二,而且会持续保持至少十年。
文章图片
1:可识别身份证正面信息+背面信息
2:可识别银行卡信息
3:可识别驾驶证+行驶证信息
4:可进行人脸识别,人脸比对,活体检测
5:可设置请求地址+用户密钥+应用密钥
6:直接传入图片即可,信号返回,毫秒级极速响应
7:通用Qt4-Qt5,windows linux 嵌入式linux
【AI人脸识别+图像识别【文末源码分享】】下面看一下演示效果
文章图片
文章图片
文章图片
当然这个是识别不了的
文章图片
1QByteArray FaceBaiDu::getImageData(const QImage &img)
2{
3QImage image = img;
4QByteArray imageData;
5QBuffer buffer(&imageData);
6image.save(&buffer, "jpg");
7return imageData.toBase64();
8}
9
10QString FaceBaiDu::getImageData2(const QImage &img)
11{
12return QString(getImageData(img));
13}
14
15QHttpPart FaceBaiDu::dataToHttpPart(const QByteArray &body, const QString &name)
16{
17QHttpPart httpPart;
18httpPart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant(QString("form-data;
name=\"%1\"").arg(name)));
19httpPart.setBody(body);
20return httpPart;
21}
22
23void FaceBaiDu::sendData(const QString &url, const QList &httpParts)
24{
25//初始化消息体
26QHttpMultiPart *httpMultiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType);
27
28//逐个添加消息内容
29foreach (QHttpPart httpPart, httpParts) {
30httpMultiPart->append(httpPart);
31}
32
33//初始化请求对象
34QNetworkRequest request;
35request.setUrl(QUrl(url));
36
37#ifdef ssl
38//设置openssl签名配置,否则在ARM上会报错
39QSslConfiguration conf = request.sslConfiguration();
40conf.setPeerVerifyMode(QSslSocket::VerifyNone);
41#if (QT_VERSION > QT_VERSION_CHECK(5,0,0))
42conf.setProtocol(QSsl::TlsV1_0);
43#else
44conf.setProtocol(QSsl::TlsV1);
45#endif
46request.setSslConfiguration(conf);
47#endif
48
49//发送请求
50QNetworkReply *reply = manager->post(request, httpMultiPart);
51httpMultiPart->setParent(reply);
52}
53
54void FaceBaiDu::finished(QNetworkReply *reply)
55{
56QString error = reply->errorString();
57if (!error.isEmpty() && error != "Unknown error") {
58emit receiveError(error);
59}
60
61if (reply->bytesAvailable() > 0 && reply->error() == QNetworkReply::NoError) {
62QString data = https://www.it610.com/article/reply->readAll();
63reply->deleteLater();
64
65//发送接收数据信号
66emit receiveData(data);
67
68//初始化脚本引擎
69QScriptEngine engine;
70//构建解析对象
71QScriptValue script = engine.evaluate("value="https://www.it610.com/article/+ data);
72
73//获取鉴权标识符
74QString token = script.property("access_token").toString();
75if (!token.isEmpty()) {
76tokenFace = token;
77tokenOcr = token;
78}
79
80//通用返回结果字段
81int code = script.property("error_code").toInt32();
82QString msg = script.property("error_msg").toString();
83emit receiveResult(code, msg);
84
85//人脸识别部分
86QScriptValue result = script.property("result");
87if (!result.isNull()) {
88//人脸识别
89QScriptValue face_list = result.property("face_list");
90if (face_list.isObject()) {
91checkFaceList(face_list);
92}
93
94//人脸比对
95QScriptValue score = result.property("score");
96if (!score.isNull()) {
97double value = https://www.it610.com/article/score.toString().toDouble();
98if (value> 0) {
99emit receiveFaceCompare(QRect(), QRect(), value);
100} else {
101emit receiveFaceCompareFail();
102}
103}
104
105//活体检测
106QScriptValue face_liveness = result.property("face_liveness");
107if (!face_liveness.isNull()) {
108double liveness = face_liveness.toString().toDouble();
109if (liveness > 0) {
110emit receiveLive(liveness);
111}
112}
113
114//银行卡
115QScriptValue bank_card_number = result.property("bank_card_number");
116if (!bank_card_number.isNull()) {
117QString card_number = bank_card_number.toString();
118QString bank_name = result.property("bank_name").toString();
119if (!card_number.isEmpty()) {
120emit receiveBankCardInfo(card_number, bank_name);
121}
122}
123}
124
125//文字识别部分
126QScriptValue words_result = script.property("words_result");
127if (!words_result.isNull()) {
128//身份证正面
129QScriptValue nation = words_result.property("民族");
130if (nation.isObject()) {
131checkCardFront(words_result);
132}
133
134//身份证反面
135QScriptValue issuedby = words_result.property("签发机关");
136if (issuedby.isObject()) {
137checkCardBack(words_result);
138}
139
140//驾驶证
141QScriptValue license_number = words_result.property("证号");
142if (license_number.isObject()) {
143checkDriverLicense(words_result);
144}
145
146//行驶证
147QScriptValue model = words_result.property("品牌型号");
148if (model.isObject()) {
149checkRVehicleLicense(words_result);
150}
151}
152}
153}
154
155void FaceBaiDu::checkFaceList(const QScriptValue &face_list)
156{
157QRect face_rectangle;
158
159//创建迭代器逐个解析具体值
160QScriptValueIterator it(face_list);
161while (it.hasNext()) {
162it.next();
163
164QString face_token = it.value().property("face_token").toString();
165if (!face_token.isEmpty()) {
166QScriptValue location = it.value().property("location");
167if (location.isObject()) {
168face_rectangle.setX(location.property("left").toInt32());
169face_rectangle.setY(location.property("top").toInt32());
170face_rectangle.setWidth(location.property("width").toInt32());
171face_rectangle.setHeight(location.property("height").toInt32());
172}
173}
174
175it.next();
176if (face_rectangle.width() > 0) {
177emit receiveFaceRect(face_rectangle);
178} else {
179break;
180}
181}
182}
183
184void FaceBaiDu::checkCardFront(const QScriptValue &scriptValue)
185{
186QScriptValue name = scriptValue.property("姓名");
187QScriptValue address = scriptValue.property("住址");
188QScriptValue birthday = scriptValue.property("出生");
189QScriptValue number = scriptValue.property("公民身份号码");
190QScriptValue sex = scriptValue.property("性别");
191QScriptValue nation = scriptValue.property("民族");
192
193QString strName = name.property("words").toString();
194QString strAddress = address.property("words").toString();
195QString strBirthday = birthday.property("words").toString();
196QString strNumber = number.property("words").toString();
197QString strSex = sex.property("words").toString();
198QString strNation = nation.property("words").toString();
199
200emit receiveIDCardInfoFront(strName, strSex, strNumber, strBirthday, strNation, strAddress);
201}
202
203void FaceBaiDu::checkCardBack(const QScriptValue &scriptValue)
204{
205QScriptValue issuedby = scriptValue.property("签发机关");
206QScriptValue dateStart = scriptValue.property("签发日期");
207QScriptValue dateEnd = scriptValue.property("失效日期");
208
209QString strIssuedby = issuedby.property("words").toString();
210QString strDataStart = dateStart.property("words").toString();
211QString strDateEnd = dateEnd.property("words").toString();
212
213QString strDate = QString("%1.%2.%3-%4.%5.%6")
214.arg(strDataStart.mid(0, 4)).arg(strDataStart.mid(4, 2)).arg(strDataStart.mid(6, 2))
215.arg(strDateEnd.mid(0, 4)).arg(strDateEnd.mid(4, 2)).arg(strDateEnd.mid(6, 2));
216emit receiveIDCardInfoBack(strDate, strIssuedby);
217}
218
219void FaceBaiDu::checkDriverLicense(const QScriptValue &scriptValue)
220{
221QScriptValue licenseNumber = scriptValue.property("证号");
222QScriptValue name = scriptValue.property("姓名");
223QScriptValue gender = scriptValue.property("性别");
224QScriptValue nationality = scriptValue.property("国籍");
225QScriptValue address = scriptValue.property("住址");
226QScriptValue birthday = scriptValue.property("出生日期");
227QScriptValue issueDate = scriptValue.property("初次领证日期");
228QScriptValue classType = scriptValue.property("准驾车型");
229QScriptValue validFrom = scriptValue.property("有效起始日期");
230QScriptValue validFor = scriptValue.property("有效期限");
231
232QString strLicenseNumber = licenseNumber.property("words").toString();
233QString strName = name.property("words").toString();
234QString strGender = gender.property("words").toString();
235QString strNationality = nationality.property("words").toString();
236QString strAddress = address.property("words").toString();
237QString strBirthday = birthday.property("words").toString();
238QString strIssueDate = issueDate.property("words").toString();
239QString strClassType = classType.property("words").toString();
240QString strValidFrom = validFrom.property("words").toString();
241QString strValidFor = validFor.property("words").toString();
242
243emit receiveDriverInfo(strValidFrom, strGender, "", strIssueDate, strClassType, strLicenseNumber,
244strValidFor, strBirthday, "1", strAddress, strNationality, strName);
245}
246
247void FaceBaiDu::checkRVehicleLicense(const QScriptValue &scriptValue)
248{
249QScriptValue plateNo = scriptValue.property("号牌号码");
250QScriptValue vehicleType = scriptValue.property("车辆类型");
251QScriptValue owner = scriptValue.property("所有人");
252QScriptValue address = scriptValue.property("住址");
253QScriptValue useCharacter = scriptValue.property("使用性质");
254QScriptValue model = scriptValue.property("品牌型号");
255QScriptValue vin = scriptValue.property("车辆识别代号");
256QScriptValue engineNo = scriptValue.property("发动机号码");
257QScriptValue registerDate = scriptValue.property("注册日期");
258QScriptValue issueDate = scriptValue.property("发证日期");
259
260QString strPlateNo = plateNo.property("words").toString();
261QString strCehicleType = vehicleType.property("words").toString();
262QString strOwner = owner.property("words").toString();
263QString strAddress = address.property("words").toString();
264QString strUseCharacter = useCharacter.property("words").toString();
265QString strModel = model.property("words").toString();
266QString strVin = vin.property("words").toString();
267QString strEngineNo = engineNo.property("words").toString();
268QString strRegisterDate = registerDate.property("words").toString();
269QString strIssueDate = issueDate.property("words").toString();
270
271emit receiveRvehicleInfo(strIssueDate, strCehicleType, "", strVin, strPlateNo, strUseCharacter,
272strAddress, strOwner, strModel, strRegisterDate, strEngineNo);
273}
274
275void FaceBaiDu::sendData(const QString &url, const QString &data, const QString &header)
276{
277QNetworkRequest request;
278request.setHeader(QNetworkRequest::ContentTypeHeader, header);
279request.setUrl(QUrl(url));
280
281#ifdef ssl
282//设置openssl签名配置,否则在ARM上会报错
283QSslConfiguration conf = request.sslConfiguration();
284conf.setPeerVerifyMode(QSslSocket::VerifyNone);
285#if (QT_VERSION > QT_VERSION_CHECK(5,0,0))
286conf.setProtocol(QSsl::TlsV1_0);
287#else
288conf.setProtocol(QSsl::TlsV1);
289#endif
290request.setSslConfiguration(conf);
291#endif
292
293manager->post(request, data.toUtf8());
294}
295
296void FaceBaiDu::getToken(const QString &client_id, const QString &client_secret)
297{
298QStringList list;
299list.append(QString("grant_type=%1").arg("client_credentials"));
300list.append(QString("client_id=%1").arg(client_id));
301list.append(QString("client_secret=%1").arg(client_secret));
302QString data = https://www.it610.com/article/list.join("&");
303
304QString url = "https://aip.baidubce.com/oauth/2.0/token";
305sendData(url, data);
306}
307
308void FaceBaiDu::detect(const QImage &img)
309{
310QStringList list;
311list.append(QString("{\"image\":\"%1\",\"image_type\":\"BASE64\"}").arg(getImageData2(img)));
312QString data = https://www.it610.com/article/list.join("");
313
314QString url = QString("https://aip.baidubce.com/rest/2.0/face/v3/detect?access_token=%1").arg(tokenFace);
315sendData(url, data);
316}
317
318void FaceBaiDu::compare(const QImage &img1, const QImage &img2)
319{
320QString imgData1 = getImageData2(img1);
321QString imgData2 = getImageData2(img2);
322
323//如果需要活体检测则NONE改为LOW NORMAL HIGH
324QStringList list;
325list.append("[");
326list.append(QString("{\"image\":\"%1\",\"image_type\":\"BASE64\",\"liveness_control\":\"NONE\"}").arg(imgData1));
327list.append(",");
328list.append(QString("{\"image\":\"%1\",\"image_type\":\"BASE64\",\"liveness_control\":\"NONE\"}").arg(imgData2));
329list.append("]");
330QString data = https://www.it610.com/article/list.join("");
331
332QString url = QString("https://aip.baidubce.com/rest/2.0/face/v3/match?access_token=%1").arg(tokenFace);
333sendData(url, data);
334}
335
336void FaceBaiDu::live(const QImage &img)
337{
338QList imgs;
339if (!img.isNull()) {
340imgs << img;
341}
342
343live(imgs);
344}
345
346void FaceBaiDu::live(const QList &imgs)
347{
348//记住最后一次处理的时间,限制频繁的调用
349QDateTime now = QDateTime::currentDateTime();
350if (lastTime.msecsTo(now) < 500) {
351return;
352}
353
354lastTime = now;
355
356QStringList list;
357list.append("[");
358
359int count = imgs.count();
360for (int i = 0;
i < count;
i++) {
361QString imgData = https://www.it610.com/article/getImageData2(imgs.at(i));
362list.append(QString("{\"image\":\"%1\",\"image_type\":\"BASE64\"}").arg(imgData));
363if (i < count - 1) {
364list.append(",");
365}
366}
367
368list.append("]");
369QString data = https://www.it610.com/article/list.join("");
370
371QString url = QString("https://aip.baidubce.com/rest/2.0/face/v3/faceverify?access_token=%1").arg(tokenFace);
372sendData(url, data);
373}
374
375void FaceBaiDu::idmatch(const QString &idcard, const QString &name)
376{
377QStringList list;
378list.append(QString("{\"id_card_num\":\"%1\",\"name\":\"%2\"}").arg(idcard).arg(name));
379QString data = https://www.it610.com/article/list.join("");
380
381QString url = QString("https://aip.baidubce.com/rest/2.0/face/v3/person/idmatch?access_token=%1").arg(tokenFace);
382sendData(url, data);
383}
384
385void FaceBaiDu::idcard(const QImage &img, bool front)
386{
387QList httpParts;
388httpParts << dataToHttpPart(front ? "front" : "back", "id_card_side");
389httpParts << dataToHttpPart(getImageData(img), "image");
390
391QString url = QString("https://aip.baidubce.com/rest/2.0/ocr/v1/idcard?access_token=%1").arg(tokenOcr);
392sendData(url, httpParts);
393}
394
395void FaceBaiDu::bankcard(const QImage &img)
396{
397QList httpParts;
398httpParts << dataToHttpPart(getImageData(img), "image");
399
400QString url = QString("https://aip.baidubce.com/rest/2.0/ocr/v1/bankcard?access_token=%1").arg(tokenOcr);
401sendData(url, httpParts);
402}
403
404void FaceBaiDu::driverLicense(const QImage &img)
405{
406QList httpParts;
407httpParts << dataToHttpPart(getImageData(img), "image");
408
409QString url = QString("https://aip.baidubce.com/rest/2.0/ocr/v1/driving_license?access_token=%1").arg(tokenOcr);
410sendData(url, httpParts);
411}
412
413void FaceBaiDu::vehicleLicense(const QImage &img)
414{
415QList httpParts;
416httpParts << dataToHttpPart(getImageData(img), "image");
417
418QString url = QString("https://aip.baidubce.com/rest/2.0/ocr/v1/vehicle_license?access_token=%1").arg(tokenOcr);
419sendData(url, httpParts);
420}
推荐阅读
- Java|Java OpenCV图像处理之SIFT角点检测详解
- 人脸识别|【人脸识别系列】| 实现自动化妆
- Spring|Spring 框架之 AOP 原理剖析已经出炉!!!预定的童鞋可以识别下发二维码去看了
- 识别人才
- 从前沿科技到现实应用,人脸识别智能门禁加速走进智慧社区
- ImageLoaders 加载图像
- JAVA图像处理系列(四)——噪声
- 《不要用爱控制我》
- 青岛机情派iPhone5s指纹识别修复
- AI芯天下丨指纹识别别有洞天,指静脉识别能否为智能家居带来什么