- 前言:基于QT平台开发的一款人脸口罩检测系统,利用百度AI-EasyDL平台搭建深度学习模型并通过api调用。
准备工作
- 1、登录百度AI-EasyDL平台,注册账号,按照帮助文档新建模型
- 2、按照帮助文档建立数据集,并给数据集标注(这里可以直接上传未标注的数据集-图片,然后跟着说明一张一张图片标注)
- 3、为模型添加数据集、训练模型、校验、发布。
- 4、点击模型页“服务详情”->立即使用即可获取到API Key和Secret Key保存备用。
数据集:
![](https://i-blog.csdnimg.cn/blog_migrate/80202c85018a0b1665a89a4e457942dc.png)
![](https://i-blog.csdnimg.cn/blog_migrate/50b538898cc8bcaa848155b84441fe1b.png)
![](https://i-blog.csdnimg.cn/blog_migrate/45aa8b46faa9a90bb20d196a9b5e5612.png)
![](https://i-blog.csdnimg.cn/blog_migrate/c81283884a1b293ab5d3a3d27804b588.png)
- 5、布局更改:在上一篇文章布局的基础上添加两个按钮:“打开文件”与“发送请求”,布局在原先的基础上稍微修改一下,如下图所示:
![](https://i-blog.csdnimg.cn/blog_migrate/6bddc770d7c057510f5ea8009cbc24d5.png)
- 6、添加以上按钮的槽函数(这里不直接右击按钮转到槽函数,而是在代码里使用connect机制)与发送请求的接收数据函数:
![](https://i-blog.csdnimg.cn/blog_migrate/b26459d2d477cc570856287036b4f910.png)
![](https://i-blog.csdnimg.cn/blog_migrate/e814245a0492989bea43f830107b6f46.png)
- 7、在构造函数中设置request按钮的文本和不可点击属性,在截图按钮的槽函数中打开request按钮的可点击属性并指定其槽函数
//设置request按钮的文本显示
ui->request->setText("获取AccessToken");
ui->request->setDisabled(true);
//设置request按钮的可点击属性
ui->request->setEnabled(true);
getAccessToken = connect(ui->request, SIGNAL(clicked()), this, SLOT(on_getAccessToken()));
获取AccessToken
- 点击获取AccessToken按钮即可触发请求函数。请求函数主要内容是设置apiKey和secretKey的内容,然后按照api文档设置请求头,以及url,最后绑定该请求对应的接收函数即可。这里在使用net相关功能时,.pro文件里需要添加QT += network来支持net应用开发。
//获取AccessToken
void MainWindow::on_getAccessToken(){
QString apiKey = "x7AfM65W69R5Z6fY8wVYvOct";//替换为个人的apiKey
QString secretKey = "qw1eG**************AV6d7oNM";//替换为个人的secretKey
QNetworkRequest request;
request.setRawHeader("Content-Type", "application/json");
request.setRawHeader("charset", "UTF-8");
QUrl url("https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id=" + apiKey + "&client_secret=" + secretKey);
request.setUrl(url);
QByteArray data;
get_accessToken = new QNetworkAccessManager(this);
connect(get_accessToken, SIGNAL(finished(QNetworkReply*)), this, SLOT(accessTokenResult(QNetworkReply*)));
get_accessToken->post(request, data);
}
- 返回结果接收函数主要是将接收到的结果进行json解析,获取其中的access_token值即可,如若收到的值没有错误,则进行修改request按钮的功能函数,修改显示文本、disconnect和重新connect。
//accessToken结果接收
void MainWindow::accessTokenResult(QNetworkReply* pReply){
if(pReply->error() == QNetworkReply::NoError){
QByteArray string = pReply->readAll();
//获取内容
QJsonParseError jsonErr;
QJsonDocument jsonDoc = QJsonDocument::fromJson(string, &jsonErr);
if (jsonDoc.isObject()){
QJsonObject jsonObj = jsonDoc.object();
accessToken = jsonObj.take("access_token").toString();
qDebug()<<"access_token:"+accessToken;
//替换request按钮功能
disconnect(getAccessToken);
ui->request->setText("识别");
connect(ui->request, SIGNAL(clicked()), this, SLOT(on_recognize()));
}
}
}
将获取到的图片转为Base64编码
- 首先在.h文件里添加私有变量QString imageDatas、公有函数void imageToBase64(QImage image);然后在.cpp文件中具体实现。
void MainWindow::imageToBase64(QImage image){
//image to base64
QByteArray imageData;
QBuffer buff(&imageData);
image.save(&buff, "jpg");
imageDatas = imageData.toBase64();
}
识别
- 首先判断imageDatas和accessToken是否为空,然后再进行发送请求步骤,在发送请求时需要按照api文档要求的json形式发送(此处需要转换),接着绑定接收数据的函数。
//识别
void MainWindow::on_recognize(){
if (imageDatas.isEmpty())
{
qDebug() << "image base64 empty";
return;
}
if (accessToken.isEmpty())
{
qDebug() << "accessToken empty";
return;
}
QUrl url;
url.setUrl("https://aip.baidubce.com/rpc/2.0/ai_custom/v1/classification/moxingkz?access_token="+accessToken);
QNetworkRequest request;
request.setUrl(url);
request.setHeader(QNetworkRequest::ContentTypeHeader,QVariant("Content-Type:application/json;charset=UTF-8"));
QJsonObject post_data;;
QJsonDocument document;
post_data.insert("image", imageDatas);
post_data.insert("image_type", "BASE64");
document.setObject(post_data);
QByteArray post_param = document.toJson(QJsonDocument::Compact);
to_recoginze = new QNetworkAccessManager(this);
connect(to_recoginze, SIGNAL(finished(QNetworkReply*)), this, SLOT(recognizeResult(QNetworkReply*)));
to_recoginze->post(request, post_param);
}
- 接收数据函数同样需要判断接收数据有没有包含错误,如果没有则按照json格式解析所需要的数据:yes与no的置信度,并打印。
//识别结果接收
void MainWindow::recognizeResult(QNetworkReply* pReply){
QByteArray replaystring = pReply->readAll();
qDebug()<<"reganizeResult()"+replaystring;
QNetworkReply::NetworkError err = pReply->error();
if(err != QNetworkReply::NoError) {
qDebug() << "Failed: " << replaystring;
}else {
//获取内容
QJsonParseError jsonErr;
QJsonDocument jsonDoc = QJsonDocument::fromJson(replaystring, &jsonErr);
//qDebug()<<jsonDoc.object();
double yesNum = 0, noNum = 0;
if (jsonDoc.isObject()){
QJsonObject jsonObj = jsonDoc.object();
QJsonValue results = jsonObj.value("results");
if (results.isArray()) {
QJsonArray resultsArray = results.toArray();
for (int i = 0; i < resultsArray.count(); i++) {
QJsonObject temp = resultsArray[i].toObject();
if(temp.take("name") == "yes")
yesNum = temp.take("score").toDouble();
else
noNum = temp.take("score").toDouble();
}
}
}
qDebug()<<yesNum;
qDebug()<<noNum;
}
}
- 识别结果如下图:
![](https://i-blog.csdnimg.cn/blog_migrate/f8294d521bda251687d1b4c94da30298.png)
![](https://i-blog.csdnimg.cn/blog_migrate/b8ff9dd94225eafe9668864b5a6cb66e.png)
打开图片进行识别
void MainWindow::