qq948463582 发表于 2020-11-24 18:02:28

4412开发板图像识别项目-通过QT制作图形界面并调用百度AI...

项目名称:图像识别项目
硬件平台:iTOP-4412开发板
https://img-blog.csdnimg.cn/img_convert/2f2e20b654f1a5540f66a4c13cebc86e.pnghttps://data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==​


接下来,我们要把摄像头拍的照片通过OPENCV显示到屏幕上,并且拍照传给百度AI的接口。
首先,我们先要初始化我们的摄像头,我们新添加一个函数,使用cvCreateCameraCapture函数从摄像头中获取视频。
cvCreateCameraCapture,初始化从摄像头中获取视频 CvCapture* cvCreateCameraCapture( int index );index:要使用的摄像头索引
函数实现:
#include <highgui.h>
#include <cv.h>
void Widget::InitCamara()//这个函数属于Widget
{    //打开摄像头   
//这句代码的意思是打开video4,括号中的參数仅仅要有:   
// 0 , -1, 202 但要依据你自己的情况改,实測204可以成功打开   
camera = cvCreateCameraCapture(204);
}
如下图所示:
https://img-blog.csdnimg.cn/img_convert/545e4d475871ef58a6e92646a52eb287.png
https://data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==​


在widget.h里面声明这个函数和参数camera 并添加头文件,代码如下:
#include <highgui.h>
#include <cv.h>
CvCapture *camera;//视频获取结构, 用来作为视频获取函数的一个参数
void InitCamara();
如下图所示:
https://img-blog.csdnimg.cn/img_convert/a8e28fe006bb63cebb378ff1494fea07.png
https://data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==​

摄像头初始化完成之后,我们要获取我们摄像头的图像,获取图像的思路是:使用定时器,时间到则去读取摄像头的图像,所以我们这里要Qtimer类,这个类里面提供了定时器
首先,我们在widget.h里面声明一个定时器,和一个槽函数,代码如下:
#include <QTimer> //包含QTimer头文件
QTimer    timer; //声明QTimer对象
private slots:   
void ReadFarme(); //声明槽函数
添加完成后如下图所示:
https://img-blog.csdnimg.cn/img_convert/65592b5d9c5d86993c73ab7a0b9cd4ab.png
https://data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==​

接着我们修改widget.cpp里面的初始化摄像头的代码,我们在初始化摄像头的函数里面开启定时器,并添加在槽函数里面获取摄像头图片
启动定时器代码:
#include <QTimer>//包含QTimer头文件
timer.start(50); //启动定时器,1000为1S ,50为50ms,超时则发出timeoout信号
添加完成后如下图所示:
https://img-blog.csdnimg.cn/img_convert/3347c80d1c6c980d63f8c921ffb9f4d6.png
https://data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==​

先在widget.h里面声明一个IplImage用来表示图像,也就是申请内存空间来存放每一帧图像,其中Ipl是Intel Image Processing Library的简写。还要在声明一个QImage,因为我们要将抓取到的帧,转换为QImage格式
IplImage*frame; //申请IplImage类型指针,就是申请内存空间来存放每一帧图像
QImage    imag; //声明QImage对象
添加完如下图所示:
https://img-blog.csdnimg.cn/img_convert/7b6a8213d57d3cf19033be7e8f6c7599.png
https://data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==​

编写槽函数,在槽函数里面获取图片,代码如下:
void Widget::ReadFarme()
{   
//从摄像头读取一张图片   
//这个函数cvQueryFrame作用是从摄像头或者文件中抓取一帧   
//参数为视频获取结构也就是我在初始化摄像头声明的CvCapture *camera;   
frame = cvQueryFrame(camera);   
//将图片格式转换成QImage格式,否则不能再lable上显示   
imag = QImage((const uchar*)frame->imageData,                     
frame->width,                           
frame->height,                           
QImage::Format_RGB888).rgbSwapped();   
//用label显示一张图片   
ui->frame->setPixmap(QPixmap::fromImage(imag));
}
添加完如下图所示:
https://img-blog.csdnimg.cn/img_convert/3d9d37eaa5c946868b52c8d22d9e974f.png
https://data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==​

   最后,我们要连接信号和槽,当计时超过我们设置的50ms以后,发出timeout信号,然后执行槽函数ReadFarme(),代码如下:
connect(&timer,***NAL(timeout()),this,SLOT(ReadFarme()));
添加完如下图所示:
https://img-blog.csdnimg.cn/img_convert/64114370aff0e118d1b005373dbdee75.png
https://data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==​

获取摄像头图像并显示在屏幕上,我就完成了,接下来我们把获取到的图线传递给百度AI的接口,然后获取百度AI接口返回的数值并把返回值显示在屏幕上。
这里我们点击widget.ui文件,如下图所示:
https://img-blog.csdnimg.cn/img_convert/492e3ee5b7fcd723531ce1750ab27be6.png
https://data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==​

右键点击pushbutton空间,选择go to slot,如下图所示:
https://img-blog.csdnimg.cn/img_convert/79c94dd4dcab5ace404dc4414575d33c.png
https://data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==​

然后在弹出的界面选择clcked,并点击ok,这样他就帮我们生成了一个槽函数,如下图所示:
https://img-blog.csdnimg.cn/img_convert/453bd4f60c1acd90a3fcb4fbdb323a9f.png
https://data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==​

转到槽成功以后,会在widget.cpp下面生成一个槽函数,并且在widget.h下自动帮我们声明和连接,这样我们就不用再手动添加了,为什么我们在使用定时器的时候不用这个办法呢,因为定时器没有实体的控件,所以我们不能直接这样操作,如下图所示:
widget.cpp
https://img-blog.csdnimg.cn/img_convert/d41ec832af66394d2808816e5b7558e5.png
https://data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==​


widget.h
https://img-blog.csdnimg.cn/img_convert/70c2b7625bb473342d9ac4b8f6fc2aba.png
https://data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==​

我们在widget.cpp自动生成的槽函数里面添加以下代码:这段代码的作用为当我们点击识别的按键的时候,会拍一张照片,并显示到屏幕上,并把拍下的照片传递给百度AI的接口进行识别,然后把识别出来的数据显示到屏幕上,
std::string PlateNumber ;   
int Ret;      
frame = cvQueryFrame(camera);   
//将图片格式转换成QImage格式,否则不能再lable上显示   
imag = QImage((const uchar*)frame->imageData,                           
frame->width,                           
frame->height,                           
QImage::Format_RGB888).rgbSwapped();   
//用label显示一张图片   
ui->picture->setPixmap(QPixmap::fromImage(imag));      

//保存图片到本地   
imag.save("./PlateNumber.jpg", "JPG", 100);      
/
/把拍下来的照片传递给百度AI接口获取车牌号   
PlateNumber = GetPlateNumber("./PlateNumber.jpg");   

//把接口返回来的数据显示到屏幕上   
ui->plateNumber->setText(QString::fromStdString(PlateNumber));
把拍下来的照片传递给百度AI接口我们使用的是我们在调用百度AI接口时定义的GetPlateNumber函数,在定义GetPlateNumber函数的时候,我们知道我们只要把图片给到接口就可以了,所以这里我们先把拍下来的图片保存到本地,也就是是板子上,然后在把他的路径通过函数穿参给到GetPlateNumber的这个函数。
https://img-blog.csdnimg.cn/img_convert/1a86ad6ae347f580c1409b33a89ca964.png
https://data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==​

添加完如下图所示:
https://img-blog.csdnimg.cn/img_convert/d21452e5828d52ae9fab4a75c70b13c3.png
https://data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==​

最后,设置中文字体,我们打开main.cpp,添加以下代码,设置我们显示的字体
QFont font;
font.setPointSize(16);
font.setFamily(("wenquanyi"));
font.setBold(false);
a.setFont(font);
添加完如下图所示:
https://img-blog.csdnimg.cn/img_convert/ff00790d109bb7a571fc61cc86b45652.png
https://data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==​


至此,我们在屏幕上显示图像并拍照发给百度AI接口并获取接口的返回值显示到板子上就已经完成了。
页: [1]
查看完整版本: 4412开发板图像识别项目-通过QT制作图形界面并调用百度AI...