Qt+OpenCV利用帧差法实现车辆识别

目录
  • 一、目标
  • 二、使用Qt界面
  • 三、代码实现

一、目标

Qt界面实现 点击 线程启动按钮播放视频

左边界面显示原视频 右边界面显示车辆识别视频

结果展示如下:

初始界面

点击线程启动后,即可车辆识别

二、使用Qt界面

设计好界面后最好先保存

对按钮设置槽函数

三、代码实现

难点在于:线程同步问题

需要使用到connect函数中的第五个参数【第五个参数 具体说明如下】

1 AutoConnection 为默认参数,由发送信号决定,如果发送信号和接受信号是同一个线程,则调用DirectConnection。如果不在同一个线程则调用QueuedConnection;

2 DirectConnection 槽函数运行于信号发送者所在的线程,效果上就像是直接在信号发送的位置调用了槽函数

3 QueuedConnection 槽函数在控制回到接收者所在线程的事件循环时被调用,槽函数运行于信号接收者所在线程。发送信号后,槽函数不会立即被调用,等到接收者当前函数执行完,进入事件循环之后,槽函数才会被调用。多线程下用这个类型

4 BlockingQueuedConnection 槽函数的调用时机与Qt::QueuedConnection 一致,不过在发送完信号后,发送者所在线程会阻塞,直到槽函数运行完。接收者和发送者绝对不能在一个线程,否则会死锁。在多线程间需要同步的场合会用到这个

5 UniqueConnection 此类型可通过 “|” 与以上四个结合在一起使用。此类型为当某个信号和槽已经连接时,在进行重复连接时就会失败,可避免重复连接。如果重复连接,槽函数会重复执行

Widget

头文件导入OpenCV包

#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include<opencv2/opencv.hpp>
#include"videothread.h"

using namespace cv;

namespace Ui {
class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT
public:
    explicit Widget(QWidget *parent = 0);
    ~Widget();
    void paintEvent(QPaintEvent *e);
private slots:
    void on_pushButton_clicked();
public slots:
    //绑定线程 需要两帧画面 原图和处理之后的图   接收由同一个信号发送来的两帧画面
    void ChangeImg(Mat oldimg,Mat newimg);
private:
    Ui::Widget *ui;
    videothread *pthread;
    QImage oldimg;
    QImage newimg;
};

#endif // WIDGET_H

源文件 界面实现 

#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
    this->pthread = new videothread("D:/00000000000003jieduanshipincailliao/carMove.mp4");
    //由于线程同步问题 需要使用第五个参数
    connect(this->pthread,SIGNAL(send2UI(Mat,Mat)),this,SLOT(ChangeImg(Mat,Mat)),Qt::BlockingQueuedConnection);
}

Widget::~Widget()
{
    delete ui;
}

void Widget::paintEvent(QPaintEvent *e)
{
    ui->label->setPixmap(QPixmap::fromImage(this->oldimg));
    ui->label_2->setPixmap(QPixmap::fromImage(this->newimg));
    //qDebug()<<"paintEvent";
}

void Widget::on_pushButton_clicked()
{
    this->pthread->start();
}

void Widget::ChangeImg(Mat oldimg,Mat newimg)
{
    //Mat是BGR 而QImage是RGB 需要转换颜色
    cvtColor(oldimg,oldimg,CV_BGR2RGB);
    cvtColor(newimg,newimg,CV_BGR2RGB);

    this->oldimg = QImage(oldimg.data,oldimg.cols,oldimg.rows,QImage::Format_RGB888);
    this->oldimg = this->oldimg.scaled(ui->label->width(),ui->label->height());

    this->newimg = QImage(newimg.data,newimg.cols,newimg.rows,QImage::Format_RGB888);
    this->newimg = this->newimg.scaled(ui->label_2->width(),ui->label_2->height());
    //update();
}

VideoThread

头文件导入OpenCV包

#ifndef VIDEOTHREAD_H
#define VIDEOTHREAD_H
#include<QThread>
#include<opencv2/opencv.hpp>
#include<vector>
#include<QDebug>
#include <QObject>

using namespace std;
using namespace cv;

class videothread : public QThread
{
    Q_OBJECT
public:
    //explicit videothread(QObject *parent = 0);
    //线程传参视频路径
    videothread(char *path);
    void run();
private:
    VideoCapture cap;
    Mat frame;//读一帧
    Mat temp;//保存上一帧
signals:
    //发送信号
    void send2UI(Mat oldimg,Mat newimg);
public slots:
};

#endif // VIDEOTHREAD_H

源文件 帧差法 车辆识别 

#include "videothread.h"

videothread::videothread(char *path):QThread()
{
    //打开一个视频
    cap.open(path);
}

void videothread::run()
{
    int count = 0;
    Mat resFrame,diff;
    Mat frontGray,afterGray;
    vector<vector<Point>>contours;

    Mat element = cv::getStructuringElement(MORPH_RECT,Size(3,3));
    Mat element2 = cv::getStructuringElement(MORPH_RECT,Size(20,20));
    int x,y,w,h;

    while (cap.read(frame))
    {
        count++;
        if(count == 1)
        {
            //保存第一帧
            temp = frame.clone();
            continue;
        }
        else {
            //绘制矩形 使用此帧
            resFrame = frame.clone();
            //1 灰度处理 目的 RGB三通道转灰度单通道 压缩到原图片三分之一大小
            cvtColor(temp,frontGray,CV_RGB2GRAY);
            cvtColor(frame,afterGray,CV_RGB2GRAY);
            //2 帧差处理 目的 找到帧与帧之间的差异(正在运动的物体)
            absdiff(frontGray,afterGray,diff);
            //3 二值化处理 目的 将灰度图继续识别转换为黑白分明的图像
            threshold(diff,diff,25,255,CV_THRESH_BINARY);
            //4 图像降噪
            //4-1 腐蚀处理 目的 去除白色噪点
            erode(diff,diff,element);
            //4-2 膨胀 目的 把白色区域变大
            dilate(diff,diff,element2);
            //5 提取关键点
            //5-1 查找特征点
            findContours(diff,contours,CV_RETR_EXTERNAL,CV_CHAIN_APPROX_SIMPLE,Point(0,0));
            //qDebug()<<contours.size();
            //5-2 提取关键点
            vector<vector<Point>>contours_poly(contours.size());
            vector<Rect>boundRect(contours.size());
            //5-3 确定下四个点来用于框选目标物体
            int num=contours.size();
            for(int i = 0;i < num;i++)
            {
                approxPolyDP(Mat(contours[i]),contours_poly[i],3,true);
                //多边拟合
                boundRect[i]=boundingRect(Mat(contours_poly[i]));
                x=boundRect[i].x;
                y=boundRect[i].y;
                w=boundRect[i].width;
                h=boundRect[i].height;
                //绘制矩形
                rectangle(resFrame,Point(x,y),Point(x+w,y+h),Scalar(0,0,255),2);
            }
        }
        temp = frame.clone();
        emit send2UI(frame,resFrame);
        msleep(1);
    }
}

主入口Qt窗口显示

#include "widget.h"
#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Widget w;
    w.show();

    return a.exec();
}

到此这篇关于Qt+OpenCV利用帧差法实现车辆识别的文章就介绍到这了,更多相关Qt OpenCV车辆识别内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • OpenCV3实现车牌识别(C++版)

    本文实例为大家分享了OpenCV3实现车牌识别的具体代码,供大家参考,具体内容如下 车牌识别(基于OpenCV3.4.7+VS2017) 视频识别 蓝色车牌识别 视觉入坑的第一个Demo(注释很详细),因为本人之前拖延,一直没能写详细实现博客,先将代码贴出来供大家交流,个人认为精华部分在字符切割(直接用指针遍历像素加限制条件切割),车牌模板已上传,整个工程也已上传,后续完善各环节实现步骤详解. 头文件:Global.h #ifdef GLOBAL extern int flag_1; exter

  • Opencv二帧差法检测运动目标与提取轮廓

    Opencv学习之二帧差法运动目标检测与轮廓提取 ,供大家参考,具体内容如下 代码是从网上摘抄学习的,加了好多注释,感觉就像边看书边做笔记一样,给人以满足的享受.Let's do this! #include "highgui.h" #include "cv.h" #include "stdio.h" #include <time.h> #include <math.h> #include <string.h>

  • C++ opencv实现车道线识别

    本文实例为大家分享了C++ opencv实现车道线识别的具体代码,供大家参考,具体内容如下 先上图 1. 2. (一)目前国内外广泛使用的车道线检测方法主要分为两大类: (1) 基于道路特征的车道线检测: (2) 基于道路模型的车道线检测. 基于道路特征的车道线检测作为主流检测方法之一,主要是利用车道线与道路环境的物理特征差异进行后续图像的分割与处理,从而突出车道线特征,以实现车道线的检测.该方法复杂度较低,实时性较高,但容易受到道路环境干扰. 基于道路模型的车道线检测主要是基于不同的二维或三维

  • opencv帧差法找出相差大的图像

    本文实例为大家分享了opencv帧差法找出相差大的图像,供大家参考,具体内容如下 #include "stdafx.h" #include <stdio.h> #include <stdlib.h> #include <iostream> #include <fstream> #include <opencv2/core/core.hpp> #include <opencv2/highgui/highgui.hpp>

  • OpenCV实现帧差法检测运动目标

    今天的目标是用OpenCV实现对运动目标的检测,这里选用三帧帧差法.代码如下: #include <opencv2/opencv.hpp> #include <cv.h> #include <highgui.h> #include <stdio.h> #include <ctype.h> double Threshold_index=0; const int CONTOUR_MAX_AERA = 200; void trackbar(int po

  • OpenCV实现车辆识别和运动目标检测

    目录 一:车辆识别成果展示 二:车辆识别超详细步骤解析 步骤一:灰度化处理 步骤二:帧差处理 步骤三:二值化处理 步骤四:图像降噪 步骤五:提取关键点 框选运动目标检测 三:车辆识别完整代码 一:车辆识别成果展示 二:车辆识别超详细步骤解析 步骤一:灰度化处理 灰度处理目的 RGB三通道转灰度单通道 压缩到原图片三分之一大小 效果展示:[避免内存浪费 帧差法对前后帧图像灰度化处理] //1 灰度处理 目的 RGB三通道转灰度单通道 压缩到原图片三分之一大小 cvtColor(frontFrame

  • opencv实现三帧差法解析

    今天和大家谈谈三帧差法来实现运动目标检测吧,其中运动检测画框实现追踪方法多种多样,大家可以自行百度,后面我也会一一实现,今天我先给大家玩玩三帧差法吧::::(注释非常清楚哦,程序也极其简单的) 帧差法是最为常用的运动目标检测和分割方法之一,基本原理就是在图像序列相邻两帧或三帧间采用基于像素的时间差分通过闭值化来提取出图像中的运动区域.首先,将相邻帧图像对应像素值相减得到差分图像,然后对差分图像二值化,在环境亮度变化不大的情况下,如果对应像素值变化小于事先确定的阂值时,可以认为此处为背景像素:如果

  • Qt+OpenCV利用帧差法实现车辆识别

    目录 一.目标 二.使用Qt界面 三.代码实现 一.目标 Qt界面实现 点击 线程启动按钮播放视频 左边界面显示原视频 右边界面显示车辆识别视频 结果展示如下: 初始界面 点击线程启动后,即可车辆识别 二.使用Qt界面 设计好界面后最好先保存 对按钮设置槽函数 三.代码实现 难点在于:线程同步问题 需要使用到connect函数中的第五个参数[第五个参数 具体说明如下] 1 AutoConnection 为默认参数,由发送信号决定,如果发送信号和接受信号是同一个线程,则调用DirectConnec

  • python+opencv实现移动侦测(帧差法)

    本文实例为大家分享了python+opencv实现移动侦测的具体代码,供大家参考,具体内容如下 1.帧差法原理 移动侦测即是根据视频每帧或者几帧之间像素的差异,对差异值设置阈值,筛选大于阈值的像素点,做掩模图即可选出视频中存在变化的桢.帧差法较为简单的视频中物体移动侦测,帧差法分为:单帧差.两桢差.和三桢差.随着帧数的增加是防止检测结果的重影. 2.算法思路 文章以截取视频为例进行单帧差法移动侦测 3.python实现代码 def threh(video,save_video,thres1,ar

  • OpenCV实现帧间差分法详解

    本文实例为大家分享了OpenCV实现帧间差分法的具体方法,供大家参考,具体内容如下 一.基本概念 基于视频的车辆检测算法种类很多:光流法检测,帧差法,背景消除法(其中包括:直方图法,平均值法,单分布和混合高斯分布背景模型,Kalman滤波等),边缘检测法,运动矢量检测法...下面分享的是运动目标检测算法中最基本的方法-帧间差分法. 相邻帧间图像差分思想:检测出了相邻两帧图像中发生变化的区域.该方法是用图像序列中的连续两帧图像进行差分,然后二值化该灰度差分图像来提取运动信息.由帧间变化区域检测分割

  • C++使用opencv处理两张图片的帧差

    本文为大家分享了使用opencv处理两张图片帧差的具体代码,供大家参考,具体内容如下 这个程序是两张图片做帧差,用C++实现的,把不同的地方用框框起来,仔细读一下程序,应该还是蛮简单的哈哈,opencv处理图片的基础. opencv配置不用我说了吧,源码cmake编译,然后导入vs即可. #include <iostream> #include <opencv2/opencv.hpp> using namespace std; using namespace cv; int mai

  • opencv利用视频的前n帧求平均图像

    本文实例为大家分享了opencv利用视频的前n帧求平均图像的具体代码,供大家参考,具体内容如下 自己写的哈,可以用该小程序对视频求解平均模型. //OpenCV中如何累加多幅图像并取平均值 #include "cv.h" #include "highgui.h" int main(int argc,char *argv[]) { int nframe = 50;//利用前nfram帧求解平均图 CvCapture *capture = cvCreateFileCap

随机推荐