上位机界面

用户登录界面设计

创建UI新窗体

选择窗口的类型

主要有3种窗体分别是QMainWindow(主窗囗),QDialog(对话窗),QWidget(空白窗体)
QMainWindow 主窗口:独立的窗体,保护状态与工具栏
Qdialog 对话窗口
:独立的窗体,空白窗体
Qwidget 小部件窗口 :必须依赖某一窗体,不独立。

SQLite数据库

SQLite3是一种轻量级的嵌入式关系型数据库管理系统,实现了自给自足的、零配置的、事务性的SQL数据库引擎。它是一个开源的项目,遵循公有领域的版权。SQLite3支持大部分的SQL语法,包括事务、触发器和存储过程。它的设计简单高效,不需要独立的服务器进程,可以直接访问存储在文件中的数据库。SQLite3适用于移动设备、嵌入式设备以及小型应用程序的开发,因为它占用资源少、易于集成,并且无需复杂的管理。SQLite3的数据库以单个文件的形式存储在磁盘上,使得数据的传输和备份变得非常方便。总的来说,SQLite3是一个功能强大且易于使用的数据库引擎,适用于许多不同的应用场景。

SQL语句

这里只列举一些SQL语句:

/*create table 创建表格*/
CREATE TABLE 表名(字段名称 1 ,字段名称 2 ,字段名称 3 ,字段名称 4 ....); 

/*insert into  插入数据*/
INSERT INTO 表名 VALUES(记录内容);                 #👉必须插满
INSERT INTO  表名(字段列表) VALUES(对应字段内容);   #👉指定字段名称插入

/*delete from  删除数据*/
DELETE FROM  表名 where 条件表达式;

/*update 修改数据*/
UPDATE 表名 SET 字段 1=字段 1 值,字段 2=字段 2 值… where 条件表达式;

/*select  查找数据*/
SELECT [*|字段列表] FROM [数据库名称].表名

1.查找表格中所有信息 
select * from  表名;

2.条件查找 
select * from  表名  where 条件表达式 

3.between   范围查找 
select * from  表名  where  money between 10 and 20;  //查找范围在10 到 20 

4.匹配查找 
select * from  表名  where  name  like "小%";  //查找名字以小字开头的内容 

5.排序查找 
SELECT  * from  car  ORDER  BY  money   DESC;  //通过money 从大到小排序 
SELECT  * from  car  ORDER  BY  money    ASC; //通过money 从小到大排序

SQL函数

SQLite 内建函数表
算术函数
abs(X) 
返回给定数字表达式的绝对值。
max(X,Y[,...]) 
返回表达式的最大值。
min(X,Y[,...]) 
返回表达式的最小值。
random(*) 
返回随机数。
round(X[,Y]) 
返回数字表达式并四舍五入为指定的长度或精度。
字符处理函数
length(X) 
返回给定字符串表达式的字符个数。
lower(X) 
将大写字符数据转换为小写字符数据后返回字符表达式。
upper(X) 
返回将小写字符数据转换为大写的字符表达式。
substr(X,Y,Z) 
返回表达式的一部分。
randstr()
quote(A)
like(A,B) 
确定给定的字符串是否与指定的模式匹配。
glob(A,B)
条件判断函数
coalesce(X,Y[,...])
ifnull(X,Y)
nullif(X,Y)
集合函数
avg(X) 
返回组中值的平均值。
count(X) 
返回组中项目的数量。
max(X) 
返回组中值的最大值。
min(X) 
返回组中值的最小值。
sum(X) 
返回表达式中所有值的和。
其他函数
typeof(X) 

SQL 数据类型

提示:SQL中的数据类型,只起说明作用不起限制作用。

派生类型

SQL 约束条件

OPenCV

OpenCV是一个开源的计算机视觉库,提供了一系列用于图像处理、计算机视觉和机器学习的函数和工具。它最初由Intel开发,现在由Willow Garage维护。OpenCV支持多种编程语言,包括C ++、Python、Java和MATLAB等。它可以在Windows、Linux、Mac OS等操作系统上运行,并且支持多种硬件平台。

OpenCV的功能包括图像处理、特征检测、对象识别、运动跟踪、人脸识别、立体视觉等。它还提供了一些机器学习算法,如支持向量机、随机森林、神经网络等,用于图像分类、目标检测等任务。

OpenCV被广泛应用于各种领域,包括医学影像分析、安防监控、自动驾驶、机器人技术等。它是一个功能强大、易于使用的计算机视觉库,为开发者提供了丰富的工具和算法,帮助他们实现各种视觉任务。

OPenCV ARM环境搭建

1.下载OpenCV源码并利用交叉编译器(arm-inux-gcc)去编译源码生成库文件

【Linux】opencv交叉编译移植到inux-arm开发板,并做测试 _opencv 交叉编译example_cpp_-CSDN博客icon-default.png?t=N7T8https://blog.csdn.net/spiremoon/article/details/105923235

2.下载并交叉编译OpenCV-ARM库

链接:https://pan.baidu.com/s/1mPtWk3pGfp8yo4l_PcftZg?pwd=1111 
提取码:1111 

3、在Pro文件中添加库文件、头文件

1.解压opencv库文件到根目录
sudo tar -xvfopencv4-arm.tar.bz
2.在et pro文件中添加opencv的头文件和库文件
INCLUDEPATH += /opencv4-arm/include
INCLUDEPATH += /opencv4-arm/include/opencv4
INCLUDEPATH +=/opencv4-arm/include/opencv4/opencv2
#添加opencv库文件
LIBS += -L/opencv4-arm/lib -lopencv world

摄像头实时监控

UDP协议

UDP(User Datagram Protocol,用户数据报协议)是一种无连接的传输层协议,它提供了一种简单的、不可靠的数据传输服务。与TCP协议不同,UDP不保证数据的可靠性和顺序传输,也不提供拥塞控制和流量控制。

UDP协议主要用于需要实时性和速度优先的应用场景,如音频、视频等流媒体传输,网络游戏和广播等。由于UDP协议的简单性和高效性,它在一些特定的应用中表现出色。

UDP协议的特点包括:

  1. 无连接:UDP不需要在数据传输前建立连接,减少了传输时延。
  2. 不可靠性:UDP不提供数据包的可靠性保证,数据包可能会丢失或重复。
  3. 快速:由于不需要建立连接和维护状态信息,UDP传输速度更快。
  4. 不提供拥塞控制:UDP不提供拥塞控制机制,容易造成网络拥塞。
  5. 支持广播和多播:UDP支持向多个目的地址发送数据,适用于广播和多播场景。

总的来说,UDP协议适用于对数据传输速度要求高、对数据可靠性要求较低的应用场景。

摄像头的打开:

#include <opencv2/opencv.hpp>
#include <opencv2/core.hpp>
#include <opencv2/videoio.hpp>
#include <opencv2/highgui.hpp>

#define WINDOWS  0

using namespace std;
using namespace cv;

//定义摄像头
VideoCapture cap(0);

#if WINDOWS

     int deviceID = 0; // 0 = open default camera  0 默认 摄像头
     int apiID = cv::CAP_ANY; // 0 = autodetect default API  0 自动 监测  摄像头采集的 格式
     cap.open(deviceID, apiID);  //打开摄像头
     if (!cap.isOpened())   //判断摄像头 是否打开
     {
         cerr << "ERROR! Unable to open camera\n";
         return ;
     }

#else

     cap.open("/dev/video7");  //打开摄像头
     if (!cap.isOpened())   //判断摄像头 是否打开
     {
         cerr << "ERROR! Unable to open camera\n";
         return ;
     }

#endif

将每一帧的图片发送给上位机:

Mat frame;
    cap >> frame; // 从摄像头获取一帧
    //判断是否获取到
    if(!frame.empty())
    {
        //将BGR转换为RGB
        cvtColor(frame,frame, cv::COLOR_BGR2RGB);
        //将Mat转化为QImage
        QImage image((unsigned char *)(frame.data),frame.cols,frame.rows,QImage::Format_RGB888);
        QByteArray byte;
        //将QByteArray转化为QBuffer
        QBuffer buff(&byte);
        //设置打开权限
        buff.open(QIODevice::WriteOnly);
        //保存图片类型为jpeg
        image.save(&buff,"jpeg");

        //发送数据
        udp->write(byte);
    }

上位机收到数据后就在标签上显示:

QByteArray buff;
    //根据可读数据来设置空间大小
    buff.resize(udp->bytesAvailable());
    //获取数据
    udp->readDatagram(buff.data(),buff.size());
    //将QByteArray转化为QBuffer
    QBuffer buffer(&buff);
    //解压缩jpeg
    QImageReader reader(&buffer,"jpeg");
    //将QByteArray转化为QImage
    QImage image;
    image.loadFromData(buff);
    //将QImage转化为QPixmap
    QPixmap pic = QPixmap::fromImage(image);
    //显示视频,并自适应窗口大小
    ui->label_7->setPixmap(pic.scaled(ui->label_7->size(), Qt::KeepAspectRatio, Qt::SmoothTransformation));

车牌识别

车牌识别是一种通过计算机视觉技术识别和识别车辆号牌的过程。它通常涉及使用摄像头捕获车辆号牌图像,然后使用光学字符识别(OCR)技术来提取和识别车牌上的字符和数字。车牌识别技术可以应用于停车管理、交通监控、安全监控、智能交通系统等领域,以提高交通管理的效率和安全性。随着人工智能和深度学习技术的不断发展,车牌识别系统的准确性和性能也在不断提升。

本文使用的是RapidOCR来实现的,本质就是文字识别,因此在测试时不要有其他文字出现在监控中。

class OCR
{
public:
    explicit OCR();
    ~OCR();
    int OCR_TextRecognition(const char *path,const char *name,char * text);

private:
    OCR_HANDLE handle;
};

OCR::OCR()
{
    //gpuIndex: -1 means use cpu, 0 means use gpu0, 1 means use gpu1...
    //OCR初始化
    handle = OcrInit(DET_MODEL, CLS_MODEL, REC_MODEL, KEY_FILE, THREAD_NUM,0);
    if (!handle) {
        printf("cannot initialize the OCR Engine.\n");

    }
}

OCR::~OCR()
{

    OcrDestroy(handle);

}

int OCR::OCR_TextRecognition(const char *path, const char *name, char *text)
{
    OCR_PARAM param = {0};
    //识别文字
    OCR_BOOL bRet = OcrDetect(handle, path, name, &param);
    if (bRet) {
        //文字长度
        int nLen = OcrGetLen(handle);
        if (nLen > 0) {
            //给文字申请堆空间
            char *szInfo = (char *) malloc(nLen);
            if (szInfo) {
                if (OcrGetResult(handle, szInfo, nLen)) {
                    //将文字拷贝到数组中
                    sprintf(text,"%s",szInfo);
                }
                //释放堆空间
                free(szInfo);
            }
        }
    }
}

所以,我们一般需要车牌定位。

//获取车牌所在ROI区域--车牌定位
bool Get_License_ROI(Mat src, License &License_ROI)
{
    Mat gray;
    cvtColor(src, gray, COLOR_BGR2GRAY);

    Mat thresh;
    threshold(gray, thresh, 0, 255, THRESH_BINARY_INV | THRESH_OTSU);

    //使用形态学开操作去除一些小轮廓
    Mat kernel = getStructuringElement(MORPH_RECT, Size(3, 3));
    Mat open;
    morphologyEx(thresh, open, MORPH_OPEN, kernel);

    //使用 RETR_EXTERNAL 找到最外轮廓
    vector<vector<Point>>contours;
    findContours(open, contours, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);
    vector<vector<Point>>conPoly(contours.size());
    for (unsigned long long i = 0; i < contours.size(); i++)
    {
        double area = contourArea(contours[i]);
        double peri = arcLength(contours[i], true);
        //根据面积筛选出可能属于车牌区域的轮廓
        if (area > 1000)
        {
            //使用多边形近似,进一步确定车牌区域轮廓
            approxPolyDP(contours[i], conPoly[i], 0.02*peri, true);

            if (conPoly[i].size() == 4)
            {
                //计算矩形区域宽高比
                Rect box = boundingRect(contours[i]);
                double ratio = double(box.width) / double(box.height);
                if (ratio > 2 && ratio < 4)
                {
                    //截取ROI区域
                    Rect rect = boundingRect(contours[i]);
                    License_ROI = { src(rect),rect };
                }
            }
        }
    }

    if (License_ROI.mat.empty())
    {
        return false;
    }
    return true;
}

RapidOCR、车牌定位源码

链接:https://pan.baidu.com/s/1NkU0k4DUANUWQb2pkb0WkQ?pwd=1111 
提取码:1111 
 

RFID刷卡

TCP协议

TCP/IP协议包含了一系列的协议,也叫TCP/IP协议族(TCP/IP Protocol Suite,或TCP/IP
Protocols),简称TCP/IP。TCP/IP协议族提供了点对点的连结机制,并且将传输数据帧的封装、寻址、传输、路由以及接收方式,都予以标准化。

Qt的TCP和UDP都比较简洁,没有C语言那么复杂。只需要初始化套接字、监听绑定就能收发了。

//实例化接送
server = new QTcpServer(this);
//监听并绑定端口
server->listen(QHostAddress::Any,8889);
//实例化发送端
clien = new QTcpSocket(this);
//连接信号与槽,执行连接成功处理函数
connect(server,&QTcpServer::newConnection,this,[&](){

clien = server->nextPendingConnection();
//连接信号与槽,执行接收处理函数
connect(clien,&QTcpSocket::readyRead,this,&MainWindow::myserver);
});

MPlayer广告播放

MPlayer:是一款开源多媒体播放器,以GNU通用公共许可证发布。
此款软件可在各主流操作系统使用,例如Linux和其他类Unix系统、Windows及Mac OS X系统。

1、下载ARM版本的MPlayer到开发板上。 

链接:https://pan.baidu.com/s/1d-nnOPKFgjngpTI7mPx6cw?pwd=1111 
提取码:1111 
 

2、将MPlayer放到指定目录下,目的是能让系统找得到MPlayer。

我个人建议是直接用QT的视频模块来做,因为当时下QT时没选视频模块,我又不想去更新就硬着头皮去做了。

如果直接使用我的源码记得把数据库删除,以免出现数据库有图片路径,但是没有该图片导致查看不了图片。

该项目上传至github链接:https://github.com/zzjabcdef/Qt_CarStop.git

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐