• 【OpenCV + Qt】 帧差法 车辆识别


    目录

    一:目标

    二:使用Qt界面

    三:代码实现


    一:目标

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

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

    结果展示如下:

    初始界面

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

    二:使用Qt界面

    设计好界面后最好先保存

    对按钮设置槽函数

    三:代码实现

    难点在于:线程同步问题

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

    1 AutoConnection 为默认参数,由发送信号决定,如果发送信号和接受信号是同一个线程,则调用DirectConnection。如果不在同一个线程则调用QueuedConnection;
    2 DirectConnection 槽函数运行于信号发送者所在的线程,效果上就像是直接在信号发送的位置调用了槽函数
    3 QueuedConnection 槽函数在控制回到接收者所在线程的事件循环时被调用,槽函数运行于信号接收者所在线程。发送信号后,槽函数不会立即被调用,等到接收者当前函数执行完,进入事件循环之后,槽函数才会被调用。多线程下用这个类型
    4 BlockingQueuedConnection 槽函数的调用时机与Qt::QueuedConnection 一致,不过在发送完信号后,发送者所在线程会阻塞,直到槽函数运行完。接收者和发送者绝对不能在一个线程,否则会死锁。在多线程间需要同步的场合会用到这个
    5 UniqueConnection 此类型可通过 “|” 与以上四个结合在一起使用。此类型为当某个信号和槽已经连接时,在进行重复连接时就会失败,可避免重复连接。如果重复连接,槽函数会重复执行

    Widget

    头文件导入OpenCV

    1. #ifndef WIDGET_H
    2. #define WIDGET_H
    3. #include
    4. #include
    5. #include"videothread.h"
    6. using namespace cv;
    7. namespace Ui {
    8. class Widget;
    9. }
    10. class Widget : public QWidget
    11. {
    12. Q_OBJECT
    13. public:
    14. explicit Widget(QWidget *parent = 0);
    15. ~Widget();
    16. void paintEvent(QPaintEvent *e);
    17. private slots:
    18. void on_pushButton_clicked();
    19. public slots:
    20. //绑定线程 需要两帧画面 原图和处理之后的图 接收由同一个信号发送来的两帧画面
    21. void ChangeImg(Mat oldimg,Mat newimg);
    22. private:
    23. Ui::Widget *ui;
    24. videothread *pthread;
    25. QImage oldimg;
    26. QImage newimg;
    27. };
    28. #endif // WIDGET_H

    源文件 界面实现 

    1. #include "widget.h"
    2. #include "ui_widget.h"
    3. Widget::Widget(QWidget *parent) :
    4. QWidget(parent),
    5. ui(new Ui::Widget)
    6. {
    7. ui->setupUi(this);
    8. this->pthread = new videothread("D:/00000000000003jieduanshipincailliao/carMove.mp4");
    9. //由于线程同步问题 需要使用第五个参数
    10. connect(this->pthread,SIGNAL(send2UI(Mat,Mat)),this,SLOT(ChangeImg(Mat,Mat)),Qt::BlockingQueuedConnection);
    11. }
    12. Widget::~Widget()
    13. {
    14. delete ui;
    15. }
    16. void Widget::paintEvent(QPaintEvent *e)
    17. {
    18. ui->label->setPixmap(QPixmap::fromImage(this->oldimg));
    19. ui->label_2->setPixmap(QPixmap::fromImage(this->newimg));
    20. //qDebug()<<"paintEvent";
    21. }
    22. void Widget::on_pushButton_clicked()
    23. {
    24. this->pthread->start();
    25. }
    26. void Widget::ChangeImg(Mat oldimg,Mat newimg)
    27. {
    28. //Mat是BGR 而QImage是RGB 需要转换颜色
    29. cvtColor(oldimg,oldimg,CV_BGR2RGB);
    30. cvtColor(newimg,newimg,CV_BGR2RGB);
    31. this->oldimg = QImage(oldimg.data,oldimg.cols,oldimg.rows,QImage::Format_RGB888);
    32. this->oldimg = this->oldimg.scaled(ui->label->width(),ui->label->height());
    33. this->newimg = QImage(newimg.data,newimg.cols,newimg.rows,QImage::Format_RGB888);
    34. this->newimg = this->newimg.scaled(ui->label_2->width(),ui->label_2->height());
    35. //update();
    36. }

    VideoThread

    头文件导入OpenCV包

    1. #ifndef VIDEOTHREAD_H
    2. #define VIDEOTHREAD_H
    3. #include
    4. #include
    5. #include
    6. #include
    7. #include
    8. using namespace std;
    9. using namespace cv;
    10. class videothread : public QThread
    11. {
    12. Q_OBJECT
    13. public:
    14. //explicit videothread(QObject *parent = 0);
    15. //线程传参视频路径
    16. videothread(char *path);
    17. void run();
    18. private:
    19. VideoCapture cap;
    20. Mat frame;//读一帧
    21. Mat temp;//保存上一帧
    22. signals:
    23. //发送信号
    24. void send2UI(Mat oldimg,Mat newimg);
    25. public slots:
    26. };
    27. #endif // VIDEOTHREAD_H

    源文件 帧差法 车辆识别 

    1. #include "videothread.h"
    2. videothread::videothread(char *path):QThread()
    3. {
    4. //打开一个视频
    5. cap.open(path);
    6. }
    7. void videothread::run()
    8. {
    9. int count = 0;
    10. Mat resFrame,diff;
    11. Mat frontGray,afterGray;
    12. vector>contours;
    13. Mat element = cv::getStructuringElement(MORPH_RECT,Size(3,3));
    14. Mat element2 = cv::getStructuringElement(MORPH_RECT,Size(20,20));
    15. int x,y,w,h;
    16. while (cap.read(frame))
    17. {
    18. count++;
    19. if(count == 1)
    20. {
    21. //保存第一帧
    22. temp = frame.clone();
    23. continue;
    24. }
    25. else {
    26. //绘制矩形 使用此帧
    27. resFrame = frame.clone();
    28. //1 灰度处理 目的 RGB三通道转灰度单通道 压缩到原图片三分之一大小
    29. cvtColor(temp,frontGray,CV_RGB2GRAY);
    30. cvtColor(frame,afterGray,CV_RGB2GRAY);
    31. //2 帧差处理 目的 找到帧与帧之间的差异(正在运动的物体)
    32. absdiff(frontGray,afterGray,diff);
    33. //3 二值化处理 目的 将灰度图继续识别转换为黑白分明的图像
    34. threshold(diff,diff,25,255,CV_THRESH_BINARY);
    35. //4 图像降噪
    36. //4-1 腐蚀处理 目的 去除白色噪点
    37. erode(diff,diff,element);
    38. //4-2 膨胀 目的 把白色区域变大
    39. dilate(diff,diff,element2);
    40. //5 提取关键点
    41. //5-1 查找特征点
    42. findContours(diff,contours,CV_RETR_EXTERNAL,CV_CHAIN_APPROX_SIMPLE,Point(0,0));
    43. //qDebug()<
    44. //5-2 提取关键点
    45. vector>contours_poly(contours.size());
    46. vectorboundRect(contours.size());
    47. //5-3 确定下四个点来用于框选目标物体
    48. int num=contours.size();
    49. for(int i = 0;i < num;i++)
    50. {
    51. approxPolyDP(Mat(contours[i]),contours_poly[i],3,true);
    52. //多边拟合
    53. boundRect[i]=boundingRect(Mat(contours_poly[i]));
    54. x=boundRect[i].x;
    55. y=boundRect[i].y;
    56. w=boundRect[i].width;
    57. h=boundRect[i].height;
    58. //绘制矩形
    59. rectangle(resFrame,Point(x,y),Point(x+w,y+h),Scalar(0,0,255),2);
    60. }
    61. }
    62. temp = frame.clone();
    63. emit send2UI(frame,resFrame);
    64. msleep(1);
    65. }
    66. }

    主入口Qt窗口显示

    1. #include "widget.h"
    2. #include
    3. int main(int argc, char *argv[])
    4. {
    5. QApplication a(argc, argv);
    6. Widget w;
    7. w.show();
    8. return a.exec();
    9. }
  • 相关阅读:
    斯坦福计算机视觉cs231n-assignment3总结
    Hadoop集群启动但是没有datanode/namenode的情况
    Pytorch实现深度学习常见问题
    第七章 树与森林
    初识HTML超文本标记语言
    sql注入攻击与防护
    java python基于Vue宠物交流网站管理系统
    c++继承
    Echarts ----写属性设置
    力扣 -- 132. 分割回文串 II
  • 原文地址:https://blog.csdn.net/m0_56051805/article/details/126132890