目录
登录到百度智能云,找到文字识别
完成操作指引
开通
查看车牌识别的api文档
编辑编辑
查看自己应用的api key
查看回应的数据格式
编程步骤
ui界面编辑
添加模块,头文件和定义变量
新建两个类,一个图像Image类,一个http类,http类继承QObject类,并添加头文件并定义成员和函数
实现图像Image类,Http类的函数
在ui界面的cpp中添加全局变量,根据自己的应用来写,开头有获取方法
编写打开图片按钮的点击事件
编写识别按钮的点击事件
登录到百度智能云,找到文字识别
完成操作指引
- 免费尝鲜---服务类型选择交通---接口选择全部----0元领取
- 创建应用---填写应用名称---个人----应用描述
开通
查看车牌识别的api文档
查看自己应用的api key
查看回应的数据格式
编程步骤
ui界面编辑
添加模块,头文件和定义变量
在pro中添加模块
QT += core gui network在ui界面类的.h里添加
#include <QDebug>
#include <QJsonArray>
#include <QJsonDocument>
#include <QJsonObject>
#include <QThread>
#include <QFileDialog>#include "image.h"
#include "http.h"
新建两个类,一个图像Image类,一个http类,http类继承QObject类,并添加头文件并定义成员和函数
Image类
#include <QString>
#include <QImage>
#include <QBuffer>
#include <QTextCodec>public:static QByteArray imageToBase64(QString fileName);
Http类
#include <QString>
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QNetworkRequest>
#include <QEventLoop>public:static bool post_syns(QString url,QMap<QString,QString>header,QByteArray& requestData,QByteArray&replyData);
实现图像Image类,Http类的函数
Image类
//将图片转换为base64位
QByteArray Image::imageToBase64(QString fileName)
{//创建一个QImage对象img,并使用传入的文件名fileName来初始化它QImage img(fileName);//创建一个空的QByteArray对象ba,用于存储图片的二进制数据QByteArray ba;//用QByteArray构造QBuffer//创建一个QBuffer对象buf,并将之前创建的QByteArray对象ba的地址传递给它。//这样,我们可以将数据写入这个缓冲区QBuffer buf(&ba);//打开缓冲区buf以进行写操作。这是为了准备将图片数据写入缓冲区buf.open(QIODevice::WriteOnly);//将图片对象img保存到缓冲区buf中,使用JPG格式。//这样,图片的二进制数据将被写入到之前创建的QByteArray对象中img.save(&buf,"JPG");//把img 写入QBuffer//将之前存储的图片二进制数据转换为Base64编码的字符串,并存储在新的QByteArray对象中QByteArray base64 = ba.toBase64();//不包含编码头//创建一个指向UTF-8编码的文本编解码器的指针。QTextCodec *codec = QTextCodec::codecForName("utf-8");//对Base64编码的字符串进行URL编码//对图片urlencodeQByteArray imaData = codec->fromUnicode(base64).toPercentEncoding();return imaData;
}
Http类
//提交http并将回应数据接收并判断是否提交成功
bool Http::post_syns(QString url, QMap<QString,QString>header, QByteArray &requestData, QByteArray &replyData)
{//创建管理者对象,负责发送和管理网络请求QNetworkAccessManager manager;//发送请求的动作//创建http请求包对象,用于存储关于HTTP请求的信息QNetworkRequest request;//请求的内容(包含url和头)//设置请求的URL为传入的url参数request.setUrl(url);//创建一个迭代器来遍历传入的请求头QMapIterator<QString,QString> it(header);//循环遍历所有的请求头while(it.hasNext()){//移动迭代器到下一个头it.next();//为请求设置一个原始头//.toLatin1()方法将字符串转换为Latin-1编码的字节数组,//因为Qt的网络模块要求头字段使用Latin-1编码request.setRawHeader(it.key().toLatin1(),it.value().toLatin1());}//使用之前设置的请求信息和请求数据发送一个POST请求,并将返回的响应对象存储在reply指针中QNetworkReply *reply = manager.post(request,requestData);//创建一个事件循环对象QEventLoop l;//当网络请求完成时,连接的信号(finished)将触发事件循环的退出槽(quit)//当网络请求完成时,事件循环会结束connect(reply,&QNetworkReply::finished,&l,&QEventLoop::quit);//开始事件循环,等待网络请求完成事件发生l.exec();//检查是否有一个有效的响应对象,并且该响应没有错误if(reply != nullptr && reply->error() == QNetworkReply::NoError){//从响应对象中读取所有的数据,并存储在replyData中replyData = reply->readAll();//返回成功return true;}else//返回失败return false;
}
在ui界面的cpp中添加全局变量,根据自己的应用来写,开头有获取方法
const QString baiduTokenUrl = "https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id=%1&client_secret=%2&";const char *client_id = ""; //APP Key
const char *secret_id = "";//Secret Key
const QString baiduImageUrl = "https://aip.baidubce.com/rest/2.0/ocr/v1/license_plate?access_token=%1";
编写打开图片按钮的点击事件
//打开图片
void Widget::on_btnOpen_clicked()
{//打开文件对话框,获取文件的路径名,返回字符串fileName = QFileDialog::getOpenFileName(this,//当前界面"打开图片",//标题".",//默认路径"Image(*.png *.bmp *.jpg);"//过滤器);//判断文件是否打开成功if(fileName.isEmpty())return ;//创建文件对象QImage img(fileName);//将图片自适应显示到label上img = img.scaled(ui->label->size());ui->label->setPixmap(QPixmap::fromImage(img));
}
编写识别按钮的点击事件
//判断有没有图片路径if(fileName.isEmpty())return ;//调用自己定义的静态函数将图片转换为base64位QByteArray img = Image::imageToBase64(fileName);//组合成包体的一部分//将"image="字符串和转换后的Base64图片数据拼接在一起,形成完整的图片数据,用于后续的网络请求QByteArray imgData = "image=" + img; //body//获取access_token,文档中提到要先获取access_token//保存回复信息的对象QByteArray replyData; //保存回复信息//组合urlQString url = QString(baiduTokenUrl).arg(client_id).arg(secret_id);//封装头部信息//创建一个QMap对象来存储HTTP头部信息。QMap<QString,QString> header; //封装头部信息//这里只插入了一个头部信息,即"Content-Type",其值为"application/x-www-form-urlencoded"header.insert(QString("Content-Type"),QString("application/x-www-form-urlencoded"));//调用自己定义的静态函数提交http//url为接口地址//header是Content-Type:application/x-www-form-urlencoded,接口文档里有规定//imgData是图片的base64数据//replyData是回应的数据bool result = Http::post_syns(url,header,imgData,replyData);//判断是否提交成功,有数据返回if(result){//从字符串中解析为一个json对象QJsonObject obj = QJsonDocument::fromJson(replyData).object();//获取对象里key为access_token的值,该值就是access_tokenaccessToken = obj.value("access_token").toString();}//清除回应的数据replyData.clear();//将url和access_token组合QString imgurl = baiduImageUrl.arg(accessToken);//调用自己定义的静态函数提交http,和第一次只是url不一样//url为接口地址//header是Content-Type:application/x-www-form-urlencoded,接口文档里有规定//imgData是图片的base64数据//replyData是回应的数据result = Http::post_syns(imgurl,header,imgData,replyData);//判断是否提交成功if(result){//打印回应的结果qDebug()<<"replyData:"<<replyData;//解析结果成一个json对象QJsonObject obj = QJsonDocument::fromJson(replyData).object();//获取key为words_result的对象QJsonValue val = obj.value("words_result");//获取key为number的值QString carId = val.toObject().value("number").toString();//输出车牌qDebug()<<"carId:"<<carId;//显示车牌ui->lineEdit->setText(carId);}else{//提交失败ui->lineEdit->setText("unkown");}