最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Qt+OpenCV實(shí)現(xiàn)目標(biāo)檢測(cè)詳解

 更新時(shí)間:2022年03月08日 09:14:38   作者:SongpingWang  
這篇文章主要介紹了如何利用Qt和OpenCV中自帶xml文件實(shí)現(xiàn)目標(biāo)檢測(cè),文中的實(shí)現(xiàn)過(guò)程講解詳細(xì),感興趣的小伙伴可以動(dòng)手試一試

一、創(chuàng)建項(xiàng)目&UI設(shè)計(jì)

創(chuàng)建項(xiàng)目,UI設(shè)計(jì)如下

文件類(lèi)型判斷

簡(jiǎn)單的判斷文件類(lèi)型

QString file("sample.jpg");
if (file.contains(".jpg") || file.contains(".bmp") || file.contains(".png"))
    qDebug()<<"這是圖片。";

推薦使用QMimeDatabase類(lèi)

QMimeDatabase db;
QMimeType mime = db.mimeTypeForFile("sample.bmp");
if (mime.name().startsWith("image/")) 
    qDebug()<<"這是圖片。";
類(lèi)型描述 示例
text普通文本text/plain,
text/html,
text/css,
text/javascript
image圖像文件(包含動(dòng)態(tài)gif)image/gif,
image/png,
image/jpeg,
image/bmp,
image/webp
audio音頻文件audio/wav,
audio/mpeg,
audio/midi,
audio/webm,
audio/ogg
video視頻文件video/mp4,
video/x-flv,
video/webm,
video/ogg
application二進(jìn)制數(shù)據(jù)application/xml,
application/pdf

二、代碼與演示

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QFileDialog>
#include <QFile>
#include <opencv2/opencv.hpp>
#include <QMainWindow>
#include <QTimer>
#include <QImage>
#include <QPixmap>
#include <QDateTime>
#include <QMutex>
#include <QMutexLocker>
#include <QMimeDatabase>
#include <iostream>

QPixmap Mat2Image(cv::Mat src);

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    void Init();
    ~MainWindow();

private slots:
    void readFrame(); //自定義信號(hào)處理函數(shù)

    void on_pushButton_OpenFile_clicked();

    void on_pushButton_StartDetect_clicked();

    void on_pushButton_StopDetect_clicked();

    void on_pushButton_FlushDevice_clicked();

private:
    Ui::MainWindow *ui;
    QTimer *timer;
    QImage *img;
    QString mp4_path = NULL;
    cv::VideoCapture *capture;
    cv::CascadeClassifier *classifier;
    std::vector<cv::Rect> bodys;
    int display_HeightWidth = 500;
    int IsDetect_ok = 0;     //用于判斷是否加載了MP4和xml
};
#endif // MAINWINDOW_H

mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"


MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    timer = new QTimer(this);
    timer->setInterval(33);
    connect(timer,SIGNAL(timeout()),this,SLOT(readFrame()));
    ui->pushButton_StartDetect->setEnabled(false);
    ui->pushButton_StopDetect->setEnabled(false);
    Init();
}

void MainWindow::Init()
{
    capture = new cv::VideoCapture();
    classifier = new cv::CascadeClassifier;
}

MainWindow::~MainWindow()
{
    capture->release();
    delete ui;
}


void MainWindow::readFrame()
{
    cv::Mat frame, hsv_img, mask_img, gray_src;
    capture->read(frame);
    if (frame.empty()) return;
//    int frame_width = capture->get(cv::CAP_PROP_FRAME_WIDTH);
//    int frame_height = capture->get(cv::CAP_PROP_FRAME_HEIGHT);
//    if (frame_width / frame_height >= 1){
//        cv::resize(frame, frame, cv::Size(display_HeightWidth, (int)(frame_height * display_HeightWidth / frame_width)));
//    }else{
//        cv::resize(frame, frame, cv::Size((int)(frame_width * display_HeightWidth / frame_height), display_HeightWidth));
//    }

    //算法一:行人檢測(cè)
    cv::cvtColor(frame, gray_src, cv::COLOR_BGR2GRAY);
    cv::equalizeHist(gray_src, gray_src);
    classifier->detectMultiScale(gray_src, bodys, 1.1, 3, 0, cv::Size(30, 30));
    for (size_t i = 0; i < bodys.size(); i++){
        cv::rectangle(frame, bodys[i], cv::Scalar(0, 0, 255), 2, 8, 0);
    }

    //算法二:顏色跟蹤
    cv::cvtColor(frame, hsv_img, cv::COLOR_BGR2HSV);
    cv::inRange(hsv_img, cv::Scalar(35, 43, 46), cv::Scalar(155, 255, 255), mask_img);
    cv::Mat kernel = getStructuringElement(cv::MORPH_RECT, cv::Size(3, 3));
    morphologyEx(mask_img, mask_img, cv::MORPH_CLOSE, kernel);
    erode(mask_img, mask_img, kernel);
    GaussianBlur(mask_img, mask_img, cv::Size(3, 3), 0, 0);
    if (cv::waitKey(30) == 27) {
        ui->textEdit_log->setText("Exit...");
        ui->label_raw->clear();
        return;
    }
    cv::cvtColor(frame, frame, cv::COLOR_BGR2RGB);
    QImage rawImage = QImage((uchar*)(frame.data),frame.cols,frame.rows,frame.step,QImage::Format_RGB888);
    ui->label_raw->setPixmap(QPixmap::fromImage(rawImage));     //顯示源圖像
    QImage dstImage = QImage((uchar*)(mask_img.data),mask_img.cols,mask_img.rows,mask_img.step,QImage::Format_Grayscale8);
    ui->label_detect->setPixmap(QPixmap::fromImage(dstImage));  //顯示圖像
}


void MainWindow::on_pushButton_OpenFile_clicked()
{
    QString filename = QFileDialog::getOpenFileName(this,"打開(kāi)文件",".","*.mp4 *.avi;;*.png *.jpg *.jpeg *.bmp");
    if(!QFile::exists(filename)){
        return;
    }
    ui->statusbar->showMessage(filename);
    IsDetect_ok +=1;
    if (IsDetect_ok ==2)
        ui->pushButton_StartDetect->setEnabled(true);
    QMimeDatabase db;
    QMimeType mime = db.mimeTypeForFile(filename);
    if (mime.name().startsWith("image/")) {
        cv::Mat src = cv::imread(filename.toLatin1().data());
        if(src.empty()){
            ui->statusbar->showMessage("圖像不存在!");
            return;
        }
        cv::Mat temp;
        if(src.channels()==4)
            cv::cvtColor(src,temp,cv::COLOR_BGRA2RGB);
        else if (src.channels()==3)
            cv::cvtColor(src,temp,cv::COLOR_BGR2RGB);
        else
            cv::cvtColor(src,temp,cv::COLOR_GRAY2RGB);
        QImage img = QImage((uchar*)temp.data,temp.cols,temp.rows,temp.step,QImage::Format_RGB888);
        ui->label_raw->setPixmap(QPixmap::fromImage(img));
        ui->label_raw->resize(ui->label_raw->pixmap()->size());
        filename.clear();
    }else if (mime.name().startsWith("video/")) {
        capture->open(filename.toLatin1().data());
        if (!capture->isOpened()){
            ui->textEdit_log->append("fail to open MP4!");
            return;
        }
        ui->textEdit_log->append(QString::fromUtf8("Open video: %1 succesfully!").arg(filename));

        //獲取整個(gè)幀數(shù)
        long totalFrameNumber = capture->get(CV_CAP_PROP_FRAME_COUNT);
        ui->textEdit_log->append(QString::fromUtf8("整個(gè)視頻共 %1 幀").arg(totalFrameNumber));
        ui->label_raw->resize(QSize(capture->get(CV_CAP_PROP_FRAME_WIDTH), capture->get(CV_CAP_PROP_FRAME_HEIGHT)));

        //設(shè)置開(kāi)始幀()
        long frameToStart = 0;
        capture->set(CV_CAP_PROP_POS_FRAMES, frameToStart);
        ui->textEdit_log->append(QString::fromUtf8("從第 %1 幀開(kāi)始讀").arg(frameToStart));

        //獲取幀率
        double rate = capture->get(CV_CAP_PROP_FPS);
        ui->textEdit_log->append(QString::fromUtf8("幀率為: %1 ").arg(rate));
    }
}

void MainWindow::on_pushButton_StartDetect_clicked()
{
    timer->start();
    ui->pushButton_StartDetect->setEnabled(false);
    ui->pushButton_StopDetect->setEnabled(true);
}

void MainWindow::on_pushButton_StopDetect_clicked()
{
    ui->pushButton_StartDetect->setEnabled(true);
    ui->pushButton_StopDetect->setEnabled(false);
    timer->stop();
}

void MainWindow::on_pushButton_FlushDevice_clicked()
{

    QString xmlfilename = QFileDialog::getOpenFileName(this,"打開(kāi)文件",".","*.xml");
    if(!QFile::exists(xmlfilename)){
        return;
    }
    ui->statusbar->showMessage(xmlfilename);
    if (!classifier->load(xmlfilename.toLatin1().data())) {
        ui->textEdit_log->append("fail to open classifier_path!");
        return;
    }
    IsDetect_ok +=1;
    ui->textEdit_log->append(QString::fromUtf8("Open xmlfile: %1 succesfully!").arg(xmlfilename));
    if (IsDetect_ok ==2)
        ui->pushButton_StartDetect->setEnabled(true);
}

演示效果

拓展閱讀

直接在屬性欄目搜索中設(shè)置(如下圖),或者 pushbutton設(shè)置icon和文字

下面是pushbutton設(shè)置icon和文字的四種方法詳解

1.使用系統(tǒng)自帶api

    ui->pushButton->setIconSize(QSize(32,32));
    ui->pushButton->setIcon(QIcon(":/images/Setting.png"));
    ui->pushButton->setText(QString::fromLocal8Bit("系統(tǒng)設(shè)置"));
    ui->pushButton->setStyleSheet("QPushButton{border:1px solid blue;background:white;}"
                                  "QPushButton:hover{border:0px;background:blue;}"
                                  "QPushButton:pressed{border:0px;background:red;}");

無(wú)法設(shè)置icon和文字之間的距離。

2.如果想讓icon顯示在文字上方可使用QToolButton

ui->toolButton->setIconSize(QSize(32,32));
    ui->toolButton->setIcon(QIcon(":/images/Setting.png"));
    ui->toolButton->setText(QString::fromLocal8Bit("系統(tǒng)設(shè)置"));
    ui->toolButton->setToolButtonStyle(Qt::ToolButtonTextUnderIcon);

3.在pushbutton上面使用label進(jìn)行布局

 QLabel *iconLabel = new QLabel;
    QLabel *textLabel = new QLabel;
    iconLabel->setFixedSize(32,32);
    iconLabel->setStyleSheet("border:1px solid red;");
    textLabel->setStyleSheet("border:1px solid red;");
    iconLabel->setPixmap(QPixmap(":/images/Setting.png"));
    textLabel->setText(QString::fromLocal8Bit("系統(tǒng)設(shè)置"));
    textLabel->setFixedWidth(60);
    QHBoxLayout *myLayout = new QHBoxLayout();
    myLayout->addSpacing(10);
    myLayout->addWidget(iconLabel);
    myLayout->addSpacing(30);
    myLayout->addWidget(textLabel);
    myLayout->addStretch();
    ui->pushButton_2->setLayout(myLayout);
    ui->pushButton_2->setStyleSheet("QPushButton{border:1px solid blue;background:white;}"
                                  "QPushButton:hover{border:0px;background:blue;}"
                                  "QPushButton:pressed{border:0px;background:red;}");

4.使用圖片,設(shè)置stylesheet即可

以上三種方法,需要設(shè)置,比較麻煩,最好還是找UI設(shè)計(jì)按鈕圖片,這樣軟件的適配性也比較好。 

到此這篇關(guān)于Qt+OpenCV實(shí)現(xiàn)目標(biāo)檢測(cè)詳解的文章就介紹到這了,更多相關(guān)Qt OpenCV目標(biāo)檢測(cè)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • QT使用QML實(shí)現(xiàn)地圖繪制虛線(xiàn)的示例代碼

    QT使用QML實(shí)現(xiàn)地圖繪制虛線(xiàn)的示例代碼

    QML提供了MapPolyline用于在地圖上繪制線(xiàn)段,這篇文章主要為大家詳細(xì)介紹了QT如何使用QML實(shí)現(xiàn)在地圖上繪制虛線(xiàn),需要的小伙伴可以參考一下
    2023-07-07
  • C++使用extern實(shí)現(xiàn)源文件變量與類(lèi)成員函數(shù)的巧妙共享

    C++使用extern實(shí)現(xiàn)源文件變量與類(lèi)成員函數(shù)的巧妙共享

    C++中使用extern關(guān)鍵字可實(shí)現(xiàn)在源文件之間共享變量與類(lèi)成員函數(shù),通過(guò)聲明變量或類(lèi)在頭文件中,再在一個(gè)源文件中定義,其他源文件通過(guò)extern引用,促使模塊化、可維護(hù)的代碼組織,這篇文章主要介紹了C++用extern實(shí)現(xiàn)源文件變量與類(lèi)成員函數(shù)的巧妙共享,需要的朋友可以參考下
    2024-03-03
  • 簡(jiǎn)介C/C++預(yù)處理器的一些工作

    簡(jiǎn)介C/C++預(yù)處理器的一些工作

    這篇文章主要介紹了C/C++預(yù)處理器的一些工作,有助于理解編譯器底層的工作流程,需要的朋友可以參考下
    2015-07-07
  • 詳解windows下C/C++的內(nèi)存泄露檢測(cè)

    詳解windows下C/C++的內(nèi)存泄露檢測(cè)

    C/C++由于其沒(méi)有垃圾回收機(jī)制,所以?xún)?nèi)存的釋放一直以來(lái)都依靠于程序員的手工釋放,因此極其容易出現(xiàn)內(nèi)存泄露的問(wèn)題,而在比較大的程序之中,查找內(nèi)存泄露是一件比較困難的事情,所以我們需要一些簡(jiǎn)便的方法來(lái)檢測(cè)內(nèi)存泄露,避免內(nèi)存泄露導(dǎo)致設(shè)備崩潰
    2021-06-06
  • QT+OpenGL實(shí)現(xiàn)簡(jiǎn)單圖形的繪制

    QT+OpenGL實(shí)現(xiàn)簡(jiǎn)單圖形的繪制

    這篇文章主要為大家詳細(xì)介紹了如何利用QT和OpenGL實(shí)現(xiàn)簡(jiǎn)單圖形的繪制,文中的示例代碼講解詳細(xì),具有一定的借鑒價(jià)值,需要的可以參考一下
    2022-12-12
  • C++計(jì)算24點(diǎn)的簡(jiǎn)單程序

    C++計(jì)算24點(diǎn)的簡(jiǎn)單程序

    這篇文章主要為大家詳細(xì)介紹了C++計(jì)算24點(diǎn)的簡(jiǎn)單程序,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-03-03
  • C++位操作的常見(jiàn)用法小結(jié)

    C++位操作的常見(jiàn)用法小結(jié)

    這篇文章主要介紹了C++位操作的常見(jiàn)用法,包括了判斷奇偶、交換兩個(gè)數(shù)、正負(fù)轉(zhuǎn)換、求絕對(duì)值等,需要的朋友可以參考下
    2014-09-09
  • C語(yǔ)言實(shí)現(xiàn)簡(jiǎn)單貪吃蛇小游戲

    C語(yǔ)言實(shí)現(xiàn)簡(jiǎn)單貪吃蛇小游戲

    這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)簡(jiǎn)單貪吃蛇小游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-09-09
  • C++ delete之靜態(tài)變量問(wèn)題詳解

    C++ delete之靜態(tài)變量問(wèn)題詳解

    這篇文章主要為大家詳細(xì)介紹了C++delete的一些問(wèn)題,學(xué)習(xí)如何動(dòng)態(tài)創(chuàng)建對(duì)象,動(dòng)態(tài)創(chuàng)建的對(duì)象與一般對(duì)象的區(qū)別,動(dòng)態(tài)創(chuàng)建的對(duì)象的初始化以及釋放動(dòng)態(tài)分配的內(nèi)存等知識(shí)點(diǎn),感興趣的朋友可以參考一下
    2021-09-09
  • vs2019 MFC實(shí)現(xiàn)office界面的畫(huà)圖小項(xiàng)目

    vs2019 MFC實(shí)現(xiàn)office界面的畫(huà)圖小項(xiàng)目

    本文主要介紹了vs2019 MFC實(shí)現(xiàn)office界面的畫(huà)圖小項(xiàng)目,對(duì)大家入門(mén)有一定的幫助,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-06-06

最新評(píng)論

增城市| 紫金县| 南江县| 金乡县| 陕西省| 海安县| 武宁县| 桂林市| 昌邑市| 龙海市| 靖宇县| 昌平区| 潍坊市| 西青区| 临武县| 临汾市| 黄平县| 乳山市| 高阳县| 六盘水市| 成都市| 石台县| 酉阳| 高密市| 靖边县| 金门县| 蒙自县| 嫩江县| 新兴县| 应用必备| 霸州市| 安阳市| 临洮县| 镇赉县| 永顺县| 定结县| 霍州市| 德州市| 开江县| 裕民县| 金门县|