欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Qt+OpenCV利用幀差法實(shí)現(xiàn)車輛識(shí)別

 更新時(shí)間:2022年08月03日 15:06:27   作者:我今年十六歲  
所謂幀差法也就是對(duì)連續(xù)圖像幀做差分運(yùn)算,其結(jié)果與定義好的閾值比較,若大于閾值則為運(yùn)動(dòng)目標(biāo)值為1,否則值為0?。本文將利用幀差法實(shí)現(xiàn)車輛識(shí)別,感興趣的可以了解一下

一、目標(biāo)

Qt界面實(shí)現(xiàn) 點(diǎn)擊 線程啟動(dòng)按鈕播放視頻

左邊界面顯示原視頻 右邊界面顯示車輛識(shí)別視頻

結(jié)果展示如下:

初始界面

點(diǎn)擊線程啟動(dòng)后,即可車輛識(shí)別

二、使用Qt界面

設(shè)計(jì)好界面后最好先保存

對(duì)按鈕設(shè)置槽函數(shù)

三、代碼實(shí)現(xiàn)

難點(diǎn)在于:線程同步問(wèn)題

需要使用到connect函數(shù)中的第五個(gè)參數(shù)【第五個(gè)參數(shù) 具體說(shuō)明如下】

1 AutoConnection 為默認(rèn)參數(shù),由發(fā)送信號(hào)決定,如果發(fā)送信號(hào)和接受信號(hào)是同一個(gè)線程,則調(diào)用DirectConnection。如果不在同一個(gè)線程則調(diào)用QueuedConnection;

2 DirectConnection 槽函數(shù)運(yùn)行于信號(hào)發(fā)送者所在的線程,效果上就像是直接在信號(hào)發(fā)送的位置調(diào)用了槽函數(shù)

3 QueuedConnection 槽函數(shù)在控制回到接收者所在線程的事件循環(huán)時(shí)被調(diào)用,槽函數(shù)運(yùn)行于信號(hào)接收者所在線程。發(fā)送信號(hào)后,槽函數(shù)不會(huì)立即被調(diào)用,等到接收者當(dāng)前函數(shù)執(zhí)行完,進(jìn)入事件循環(huán)之后,槽函數(shù)才會(huì)被調(diào)用。多線程下用這個(gè)類型

4 BlockingQueuedConnection 槽函數(shù)的調(diào)用時(shí)機(jī)與Qt::QueuedConnection 一致,不過(guò)在發(fā)送完信號(hào)后,發(fā)送者所在線程會(huì)阻塞,直到槽函數(shù)運(yùn)行完。接收者和發(fā)送者絕對(duì)不能在一個(gè)線程,否則會(huì)死鎖。在多線程間需要同步的場(chǎng)合會(huì)用到這個(gè)

5 UniqueConnection 此類型可通過(guò) “|” 與以上四個(gè)結(jié)合在一起使用。此類型為當(dāng)某個(gè)信號(hào)和槽已經(jīng)連接時(shí),在進(jìn)行重復(fù)連接時(shí)就會(huì)失敗,可避免重復(fù)連接。如果重復(fù)連接,槽函數(shù)會(huì)重復(fù)執(zhí)行

Widget

頭文件導(dǎo)入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:
    //綁定線程 需要兩幀畫(huà)面 原圖和處理之后的圖   接收由同一個(gè)信號(hào)發(fā)送來(lái)的兩幀畫(huà)面
    void ChangeImg(Mat oldimg,Mat newimg);
private:
    Ui::Widget *ui;
    videothread *pthread;
    QImage oldimg;
    QImage newimg;
};
 
#endif // WIDGET_H

源文件 界面實(shí)現(xiàn) 

#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");
    //由于線程同步問(wèn)題 需要使用第五個(gè)參數(shù)
    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 需要轉(zhuǎn)換顏色
    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

頭文件導(dǎo)入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:
    //發(fā)送信號(hào)
    void send2UI(Mat oldimg,Mat newimg);
public slots:
};
 
#endif // VIDEOTHREAD_H

源文件 幀差法 車輛識(shí)別 

#include "videothread.h"
 
videothread::videothread(char *path):QThread()
{
    //打開(kāi)一個(gè)視頻
    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三通道轉(zhuǎn)灰度單通道 壓縮到原圖片三分之一大小
            cvtColor(temp,frontGray,CV_RGB2GRAY);
            cvtColor(frame,afterGray,CV_RGB2GRAY);
            //2 幀差處理 目的 找到幀與幀之間的差異(正在運(yùn)動(dòng)的物體)
            absdiff(frontGray,afterGray,diff);
            //3 二值化處理 目的 將灰度圖繼續(xù)識(shí)別轉(zhuǎn)換為黑白分明的圖像
            threshold(diff,diff,25,255,CV_THRESH_BINARY);
            //4 圖像降噪
            //4-1 腐蝕處理 目的 去除白色噪點(diǎn)
            erode(diff,diff,element);
            //4-2 膨脹 目的 把白色區(qū)域變大
            dilate(diff,diff,element2);
            //5 提取關(guān)鍵點(diǎn)
            //5-1 查找特征點(diǎn)
            findContours(diff,contours,CV_RETR_EXTERNAL,CV_CHAIN_APPROX_SIMPLE,Point(0,0));
            //qDebug()<<contours.size();
            //5-2 提取關(guān)鍵點(diǎn)
            vector<vector<Point>>contours_poly(contours.size());
            vector<Rect>boundRect(contours.size());
            //5-3 確定下四個(gè)點(diǎn)來(lái)用于框選目標(biāo)物體
            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();
}

到此這篇關(guān)于Qt+OpenCV利用幀差法實(shí)現(xiàn)車輛識(shí)別的文章就介紹到這了,更多相關(guān)Qt OpenCV車輛識(shí)別內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C++定時(shí)器實(shí)現(xiàn)和時(shí)間輪介紹

    C++定時(shí)器實(shí)現(xiàn)和時(shí)間輪介紹

    這篇文章主要介紹了C++定時(shí)器實(shí)現(xiàn)和時(shí)間輪介紹,定時(shí)器可以由很多種數(shù)據(jù)結(jié)構(gòu)實(shí)現(xiàn),比如最小堆、紅黑樹(shù)、跳表、甚至數(shù)組都可以,其本質(zhì)都是拿到最小時(shí)間的任務(wù),然后取出該任務(wù)并執(zhí)行,更多相關(guān)內(nèi)容介紹,需要的小伙伴可以參考一下
    2022-09-09
  • 深入解讀C++中的指針變量

    深入解讀C++中的指針變量

    這篇文章主要介紹了深入解讀C++中的指針變量,是C語(yǔ)言入門學(xué)習(xí)中的基礎(chǔ)知識(shí),需要的朋友可以參考下
    2015-09-09
  • C++中vector容器的用法

    C++中vector容器的用法

    在c++中,vector是一個(gè)十分有用的容器。這篇文章主要介紹了C++ vector容器的用法的相關(guān)資料,非常不錯(cuò)具有參考借鑒價(jià)值,需要的朋友可以參考下
    2016-10-10
  • C++?數(shù)據(jù)結(jié)構(gòu)超詳細(xì)講解順序表

    C++?數(shù)據(jù)結(jié)構(gòu)超詳細(xì)講解順序表

    程序中經(jīng)常需要將一組數(shù)據(jù)元素作為整體管理和使用,需要?jiǎng)?chuàng)建這種元素組,用變量記錄它們,傳進(jìn)傳出函數(shù)等。一組數(shù)據(jù)中包含的元素個(gè)數(shù)可能發(fā)生變化,順序表則是將元素順序地存放在一塊連續(xù)的存儲(chǔ)區(qū)里,元素間的順序關(guān)系由它們的存儲(chǔ)順序自然表示
    2022-03-03
  • C語(yǔ)言GetStdHandle函數(shù)使用方法

    C語(yǔ)言GetStdHandle函數(shù)使用方法

    這篇文章介紹了C語(yǔ)言GetStdHandle函數(shù)的使用方法,對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-12-12
  • C語(yǔ)言實(shí)現(xiàn)自行車存放管理系統(tǒng)

    C語(yǔ)言實(shí)現(xiàn)自行車存放管理系統(tǒng)

    這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)自行車存放管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-08-08
  • 深入分析為Visual Assist設(shè)置快捷鍵的方法

    深入分析為Visual Assist設(shè)置快捷鍵的方法

    本篇文章是對(duì)為Visual Assist設(shè)置快捷鍵的方法進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
    2013-05-05
  • c# 實(shí)現(xiàn)獲取漢字十六進(jìn)制Unicode編碼字符串的實(shí)例

    c# 實(shí)現(xiàn)獲取漢字十六進(jìn)制Unicode編碼字符串的實(shí)例

    下面小編就為大家?guī)?lái)一篇c# 實(shí)現(xiàn)獲取漢字十六進(jìn)制Unicode編碼字符串的實(shí)例。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-01-01
  • C++?this原理與可變參數(shù)及友元函數(shù)友元類分步詳解用法

    C++?this原理與可變參數(shù)及友元函數(shù)友元類分步詳解用法

    可變參數(shù)模板(variadic?templates)是C++11新增的強(qiáng)大的特性之一,它對(duì)模板參數(shù)進(jìn)行了高度泛化,能表示0到任意個(gè)數(shù)、任意類型的參數(shù),這篇文章主要介紹了C++?this原理與可變參數(shù)及友元函數(shù)友元類
    2022-11-11
  • c語(yǔ)言標(biāo)準(zhǔn)庫(kù)中字符轉(zhuǎn)換函數(shù)和數(shù)字轉(zhuǎn)換函數(shù)

    c語(yǔ)言標(biāo)準(zhǔn)庫(kù)中字符轉(zhuǎn)換函數(shù)和數(shù)字轉(zhuǎn)換函數(shù)

    這篇文章主要介紹了c標(biāo)準(zhǔn)庫(kù)中字符轉(zhuǎn)換函數(shù)和數(shù)字轉(zhuǎn)換函數(shù),需要的朋友可以參考下
    2014-04-04

最新評(píng)論