一般需要环境变量 这种的,最好只留一个, 环境变量总有一个在前一个在后,还会出现其他的动态库问题。如果非要这样用,就用哪个把哪个对应的所有环境变量都置顶
不知道你这个问题是否已经解决, 如果还没有解决的话:本景物识别功能主要原理就是利用了百度AI平台已经成熟的景物识别技术来在OpenCV上实现对自然景物图像的识别,整个流程如下:
1.在百度AI平台上创建应用,获取API KEY和Secret KEY。
2.根据获取到的API KEY和Secret KEY在OpenCV上通过编程向服务器发起请求来获取access_token。
3.打开待识别图像后对图像做base64编码和urlencode编码。
4.向服务器发起请求并处理服务器返回的数据。
首先设计界面,在QT中的UI界面中进行设计,使用了QLabel、QPushButton、QGroupBox、Line Edit等控件,设计方面比较简单,注意宽高的数值会让界面更美观,这里的icon都是在阿里巴巴矢量库找的,十分好用,也推荐给大家。(在这里我插入了背景图,十分简单,在后面我会说到)
iconfont-阿里巴巴矢量图标库然后进行图像的编码处理 ,在源文件上添加一个C++ class文件主要用于对图像进行压缩处理,在此文件中写入函数对图片进行base64编码和urlencode编码。
下一步是获取access_token,此处较为重要,通过这个数值来与百度AI建立连接,调用百度成熟的图像识别技术,具体需要在百度智能云上注册账号,注册使用方法在我的另一篇文章有详细描述。基于Python的语音识别控制系统_兰斯洛特.的博客-CSDN博客_基于python的语音识别系统
利用API KEY和Secret KEY来获取access_token,新建一个类来用于向服务器发送请求来得到access_token,我们在这一步只需要一个url即可发送请求。在函数中写入一个死循环,如果收到了请求返回的数据则跳出死循环并读出数据。
最后进行景物识别,这里使用的百度智能云中的图像识别中的动物识别,还有其他很多种识别,像植物识别、车牌识别,百度智能云功能很多,使用时还是需要慢慢找一下。
利用获取到的access_token对百度AI识别平台中动物识别对应的url发出请求,并返回识别结果。这里返回的数据是一个数组,我们先把数组解析出来,然后进行判断是否已经解析出数组,解析成功后读取识别概率最大的第一个元素,类型为QJsonValue类型。最终将结果显示在lineEdit中,如果这中间的任意一个环节出现问题没有进入到解析数组的if语句中,则返回未知。
好现在我们来看看识别的结果,打开一张图片后点击开始识别,经过一段时间后会在右侧下方显示出识别的文字结果,经过了许多测试,识别结果还是比较好的。
下面附上代码(上面的图片有文件目录就不放了,代码顺序也是根据上面图片的顺序)
pro文件里要将这行进行添加:
QT += core gui network axcontainer winextras
image.h
#ifndef IMAGE_H
#define IMAGE_H
#include <QString>
#include <QImage>
#include <QBuffer>
#include <QTextCodec>
#include <QByteArray>
class image
{
public:
image();
static QByteArray imageToBase64(QString filename);
};
#endif // IMAGE_H
image.cpp
#include "image.h"
image::image()
{
}
QByteArray image::imageToBase64(QString filename)
{
QImage img(filename);
QByteArray ba;
QBuffer buf(&ba); //用QByteArray构造QBuffer
buf.open(QIODevice::WriteOnly);
img.save(&buf, "JPG"); //把img写入QBuffer
QByteArray base64 = ba.toBase64(); //对图片做base64编码
QTextCodec *codec = QTextCodec::codecForName("UTF-8");
//对图片urlencode
QByteArray imgData = codec->fromUnicode(base64).toPercentEncoding();
return imgData;
}
http.h
#ifndef HTTP_H
#define HTTP_H
#include <QString>
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QNetworkRequest>
#include <QEventLoop>
#include <QObject>
class Http : public QObject
{
Q_OBJECT
public:
Http();
static bool post_sync(QString Url, QMap<QString,
QString> header, QByteArray &requestData, QByteArray &replyData);
};
#endif // HTTP_H
http.cpp
#include "http.h"
Http::Http()
{
}
bool Http::post_sync(QString Url, QMap<QString, QString>
header, QByteArray &requestData, QByteArray &replyData)
{
QNetworkAccessManager manager; //发送请求的动作
QNetworkRequest request; //请求的内容(包含url和头)
request.setUrl(Url);
QMapIterator<QString, QString> it(header);
while (it.hasNext())
{
it.next();
request.setRawHeader(it.key().toLatin1(), it.value().toLatin1());
}
QNetworkReply *reply = manager.post(request, requestData);//接收返回结果
QEventLoop l;
connect(reply, &QNetworkReply::finished, &l, &QEventLoop::quit);
l.exec(); //死循环
if (reply != nullptr && reply->error() == QNetworkReply::NoError)
{
replyData = reply->readAll();
return true;
}
else
{
return false;
}
}
mainwindow.cpp
void MainWindow::on_pushButton_3_clicked()//开始识别
{
QByteArray img = image::imageToBase64(filename); //image=xxxxxxx
QByteArray imgData = "image=" + img; //body
//获取access_token
QByteArray replyData; //保存回复信息
QString url = QString(baiduTokenUrl).arg(client_id).arg(secret_id);
QMap<QString, QString> header; //封装头部信息
header.insert(QString("Content-Type"), QString("application/x-www-form-urlencoded"));
QString accessToken;
bool result = Http::post_sync(url, header, imgData, replyData);
if (result)
{
QJsonObject obj = QJsonDocument::fromJson(replyData).object();
accessToken = obj.value("access_token").toString();
}
replyData.clear();
QString imgUrl = baiduImageUrl.arg(accessToken);
result = Http::post_sync(imgUrl, header, imgData, replyData);
if (result)
{
QJsonObject obj = QJsonDocument::fromJson(replyData).object();
QJsonValue val = obj.value("result");
if (val.isArray())
{
QJsonValue first = val.toArray().at(0);
if (first.isObject())
{
QString name = first.toObject().value("name").toString();
ui->lineEdit->setText(name);
return;
}
}
}
ui->lineEdit->setText("未知");
}