qt学习:http+访问百度智能云api实现车牌识别

news2024/11/18 19:49:41

目录

登录到百度智能云,找到文字识别

 完成操作指引

开通

查看车牌识别的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编码
    //对图片urlencode
    QByteArray 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; //保存回复信息
    //组合url
    QString 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_token
        accessToken = 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");
    }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1417622.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

深度学习之卷积神经网络进阶版

上一讲我们介绍了卷积神经网络和多层感知机&#xff0c;也就是全链接网络。他们在网络架构上是串行的结构&#xff0c;也就是在每一层与每一层之间&#xff0c;前面一层的输出&#xff0c;是后面一层的输入。 在神经网络里面&#xff0c;我们可能会有更加复杂的结构&#xff0…

Pycharm连接云算力远程服务器(AutoDL)训练深度学习模型全过程

前言&#xff1a;在上一篇windows搭建深度学习环境中&#xff0c;我试图使用笔记本联想小新air14的mx350显卡训练一个图像检测的深度学习模型&#xff0c;但是训练时长大概需要几天时间远超我的预期&#xff0c;所以我便选择租用GPU进行训练&#xff0c;在对多家平台对比后找到…

[BT]小迪安全2023学习笔记(第19天:Web开发-.NET项目)

第19天 名词解释 .NET 是一种由Microsoft开发的软件框架&#xff0c;用于构建和运行Windows操作系统上的应用程序。它提供了一个广泛的工具和库集合&#xff0c;支持多种编程语言&#xff0c;包括C#、VB.NET、F#等。.NET的主要目标是提供一种一致的开发平台&#xff0c;使开发…

《HTML 简易速速上手小册》第1章:HTML 入门(2024 最新版)

文章目录 1.1 HTML 简介与历史&#xff08;&#x1f609;&#x1f310;&#x1f47d;踏上神奇的网页编程之旅&#xff09;1.1.1 从过去到现在的华丽蜕变1.1.2 市场需求 —— HTML的黄金时代1.1.3 企业中的实际应用 —— 不只是个网页1.1.4 职业前景 —— 未来属于你 1.2 基本 H…

SQL注入:二次注入

SQL注入系列文章&#xff1a; 初识SQL注入-CSDN博客 SQL注入&#xff1a;联合查询的三个绕过技巧-CSDN博客 SQL注入&#xff1a;报错注入-CSDN博客 SQL注入&#xff1a;盲注-CSDN博客 目录 什么是二次注入&#xff1f; 二次注入演示 1、可以注册新用户 2、可以登录->…

数据湖技术之平台建设篇2

数据湖技术之平台建设篇1&#xff0c;主要介绍了湖仓平台建设的前三个主要工作&#xff0c;本次主要继续上次的建设工作介绍&#xff0c;聊一聊一站式湖仓服务平台的相关管理能力建设以及针对小文件的处理。 一. 一站式湖仓服务平台的相关管理能力 主要是将相关能力落地到平台…

day03-今日佳人功能实现

课程说明 首页功能说明系统架构说明实现今日佳人功能实现推荐用户的列表接口增加缓存功能整合前端联调测试 1、首页 在用户登录成功后&#xff0c;就会进入首页&#xff0c;首页中有今日佳人、推荐好友、探花、搜附近等功能。 2、系统架构 在开发完SSO系统中的登录功能后&…

【Spring实战】31 Spring Boot3 集成 Gateway 微服务网关

文章目录 1. 定义2. 功能3. 示例代码1) 创建一个业务服务2&#xff09;创建一个网关服务3&#xff09;启动服务4&#xff09;验证 4. 代码参考结语 1. 定义 Spring Cloud Gateway 是一个基于 Spring Framework 的开源网关服务&#xff0c;用于构建微服务架构中的 API 网关。它…

SpringCloud LoadBalancer

SpringCloud LoadBalancer 1.什么是LoadBalancer LoadBalancer&#xff08;负载均衡器&#xff09;是一种网络设备或软件机制&#xff0c;用于分发传入的网络流量负载请求到多个后端目标服务器上&#xff0c;从而实现系统资源的均衡利用和提高系统的可用性和性能。 负载均衡器…

前端工程化之:webpack1-7(入口和出口)

前置知识 node 环境下 "./" 代表的意思&#xff1a; 模块化代码中&#xff0c;比如 require("./") &#xff0c;表示当前 js 文件所在的目录。在路径处理中&#xff0c; "./" 表示 node 运行目录。__dirname&#xff1a;所有情况下&#xff0c;…

Python tkinter (8) ——Spinbox控件

Python的标准Tk GUI工具包的接口 tkinter系列文章 python tkinter窗口简单实现 Python tkinter (1) —— Label标签 Python tkinter (2) —— Button标签 Python tkinter (3) —— Entry标签 Python tkinter (4) —— Text控件 Python tkinter (5) 选项按钮与复选框 Pyt…

数据结构【图的遍历】

数据结构之图 图的类型定义和存储结构图的遍历遍历的定义图的特点图常用的遍历深度优先搜索 DFS&#xff08;DepthFirstSearch&#xff09;算法实现算法效率分析 广度优先搜索 BFS&#xff08;BreadthFirstSearch&#xff09;算法实现算法效率分析 DFS与BFS算法效率比较 图的类…

iOS_Xcode_LLDB调试常用命令

文章目录 结构常用命令&#xff1a;1、流程控制&#xff1a;2、常用命令3、进程信息&#xff1a;4、寄存器&#xff1a;register5、镜像&#xff1a;image6、内存&#xff1a;memory7、符号断点&#xff1a;breakpoint8、内存断点&#xff1a;watchpoint9、Tips&#xff1a; 结…

【HarmonyOS应用开发】开发介绍 DevEco Studio安装与使用(一)

内容比较长&#xff0c;干货满满&#xff0c;全是实战操作内容&#xff0c;希望耐心观看&#xff0c;如果对你有所帮助&#xff0c;请点个赞&#xff01; 官方文档&#xff1a;https://developer.huawei.com/consumer/cn/training/course/slightMooc/C101667303102887820 访…

华为OD-华为机试精讲500篇系列文章目录介绍(持续补充ing)

目录 背景介绍 什么是华为OD&#xff1f; OD现状 OD趋势 华为OD机考刷题攻略 1、刷题资料&#xff1a;投递岗位通过筛选后提供 2、注意事项&#xff1a; 真题代码目录 背景介绍 经济下行的这几年&#xff0c;每个人都感同身受&#xff0c;如何让自己在芸芸众生中脱颖而…

ubuntu中的rsyslog

目录 1. rsyslog简介 2. 查看/var/log 3. syslog的配置文件 3.1 /etc/rsyslog.d/50-default.conf 3.2 /etc/rsyslog.conf 4. 如何写入syslog 4.1 C语言 4.2 shell 4.3 内核输出 5. syslog.1和syslog.2.gz等文件是如何生成 6. logrotate是如何被执行 7. 如何限制sys…

linux 运行vue项目

1&#xff1a;在本地电脑 项目跟目录 执行 npm run build 在根目录生成文件夹 dist 2&#xff1a;复制dist 到linux 上 /usr/vuespace/ledger-web/dist 3: 配置nginx server {listen 443 ssl;server_name tz.i569.cn; #填写绑定证书的域名ssl_certificate /etc/nginx/myconf…

蓝桥杯备战——8.DS1302时钟芯片

1.分析原理图 由上图可以看到&#xff0c;芯片的时钟引脚SCK接到了P17,数据输出输入引脚IO接到P23,复位引脚RST接到P13。 2.查阅DS1302芯片手册 具体细节还需自行翻阅手册&#xff0c;我只截出重点部分 总结&#xff1a;数据在上升沿写出&#xff0c;下降沿读入&#xff0c;…

赚钱的雏形,是跑通最小闭环!

没赚钱本事&#xff0c;就专心打磨武器&#xff01; 很多人有一个错误的认知&#xff0c;就是做项目一定是新的&#xff0c;一定是有创新在里面&#xff0c;但其实赚钱的开始&#xff0c;一定是复制现有的项目。 现有的项目&#xff0c;可以确保他有市场&#xff0c;能够跑通&a…

Ps:段落面板

Ps菜单&#xff1a;窗口/段落 Window/Paragraph Ps菜单&#xff1a;文字/面板/段落面板 Type/Panels/Paragraph Panel 对于“点文本”&#xff0c;默认一行为一个段落。每按一次回车键&#xff0c;就多出一个段落。 对于“段落文本”&#xff0c;一段可能有多行&#xff0c;具体…