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

基于Qt和Opencv實現(xiàn)二維碼解析

 更新時間:2024年11月22日 15:22:44   作者:極客晨風(fēng)  
這篇文章主要為大家詳細介紹了如何利用?Qt?和?OpenCV?實現(xiàn)一個可從視頻和圖片中檢測二維碼的軟件,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下

本文詳細講解了如何利用 Qt 和 OpenCV 實現(xiàn)一個可從視頻和圖片中檢測二維碼的軟件。代碼實現(xiàn)了視頻解碼、多線程處理和界面更新等功能,是一個典型的跨線程圖像處理項目。以下分模塊對代碼進行解析。

一、項目的整體結(jié)構(gòu)

項目分為以下幾部分:

主窗口 (MainWindow) :負責(zé)界面的加載、初始化和用戶交互。

工作線程 (mThread):處理耗時的圖像處理任務(wù)(如二維碼識別)。

二維碼檢測邏輯:使用 OpenCV 進行二維碼檢測,支持圖片和視頻兩種數(shù)據(jù)來源。

多線程通信:通過信號與槽機制,在主線程和工作線程之間傳遞狀態(tài)與數(shù)據(jù)。

二、主窗口功能解析

1. 初始化界面和變量

MainWindow 類的構(gòu)造函數(shù)調(diào)用了 initializeUI() 和 initializeVariable(),分別完成了界面的樣式加載和核心變量的初始化。

void MainWindow::initializeVariable()
{
    m_tip = nullptr;

    m_lamp[0] = QImage(":/Img/e.png");
    m_lamp[1] = QImage(":/Img/i.png");
    m_lamp[2] = QImage(":/Img/w.png");

    mthread = new mThread();  // 創(chuàng)建工作線程
    m_Threadrun = false;

    // 線程信號與主窗口槽函數(shù)的連接
    connect(mthread, SIGNAL(RuningState(bool)), this, SLOT(onRespondThreadRuningState(bool)));
    connect(mthread, SIGNAL(errors(QString)), this, SLOT(onRespondThreaderrors(QString)));
    connect(mthread, SIGNAL(infors(QString)), this, SLOT(onRespondThreadinfors(QString)));
    connect(mthread, SIGNAL(warings(QString)), this, SLOT(onRespondThreadwarings(QString)));
    connect(mthread, &mThread::imageProcessed, this, &MainWindow::processImage);
}

2. 啟動和停止線程

用戶點擊按鈕后,調(diào)用 on_btn_Start_Stop_clicked,判斷當(dāng)前線程狀態(tài)以啟動或停止工作線程。

void MainWindow::on_btn_Start_Stop_clicked()
{
    m_Threadrun ? mthread->stop() : mthread->start(); // 根據(jù)當(dāng)前狀態(tài)啟動或停止線程
}

3. 文件選擇

QFileDialog 被用來讓用戶選擇視頻或圖像文件,并將這些參數(shù)傳遞到線程處理。

void MainWindow::on_btn_Loadfile_clicked()
{
    QString fileName = QFileDialog::getOpenFileName(nullptr, tc("選擇視頻文件"), "", tc("視頻文件(*.mp4)"));
    mthread->setFunId(0); // 設(shè)置功能 ID:0 表示處理視頻
    if (!fileName.isEmpty())
        mthread->setThreadParams(fileName); // 傳遞參數(shù)到線程
}

void MainWindow::on_btn_Loadimages_clicked()
{
    QStringList fileNames = QFileDialog::getOpenFileNames(nullptr, tc("選擇圖像文件"), "", tc("圖片文件(*.jpg *.bmp *.png)"));
    mthread->setFunId(1); // 設(shè)置功能 ID:1 表示處理圖片
    if (!fileNames.isEmpty())
        mthread->setThreadParams(fileNames);
}

三、工作線程實現(xiàn)

mThread 類繼承自 QThread,用于處理耗時的二維碼檢測任務(wù)。其主要功能包括:

根據(jù)功能 ID 分別處理視頻或圖片。

在每幀中調(diào)用 OpenCV 的 QRCodeDetector 進行二維碼檢測。

通過信號將處理后的圖像和數(shù)據(jù)傳遞回主線程。

1. 核心線程邏輯

線程的運行邏輯集中在 run() 方法中。getFunId() 決定了是處理視頻還是圖片,分別調(diào)用 anayVideo() 或 anayImages()。

void mThread::run()
{
    m_isRun = true;
    emit RuningState(true); // 通知主線程:線程開始運行
    emit infors(tc("線程啟動"));

    switch (getFunId()) {
    case 0:
        anayVideo(); // 處理視頻
        break;
    case 1:
        anayImages(); // 處理圖片
        break;
    default:
        break;
    }

    emit RuningState(false); // 通知主線程:線程結(jié)束運行
    emit infors(tc("線程退出"));
}

2. 視頻處理

在 anayVideo() 中,使用 OpenCV 的 VideoCapture 解碼視頻逐幀處理。每一幀調(diào)用 delectDecoded() 檢測二維碼,并通過信號將結(jié)果傳回主線程。

void mThread::anayVideo()
{
    cv::VideoCapture cap;
    if (!cap.open(m_Params.toString().toLocal8Bit().data()) || !cap.isOpened())
    {
        emit errors(tc("視頻未打開"));
        m_isRun = false;
    }
    else
    {
        cv::Mat frame;
        int frameCount = cap.get(cv::CAP_PROP_FRAME_COUNT);
        while ((frameCount--) > 0 && m_isRun) // 幀循環(huán)
        {
            cap >> frame; // 讀取一幀
            if (frame.empty())
                break;

            QString msg;
            delectDecoded(frame, msg); // 檢測二維碼
            emit imageProcessed(MatToQImage(frame), msg); // 發(fā)射處理信號
            cv::waitKey(50);
        }
        cap.release();
    }
}

3. 圖片處理

圖片處理邏輯與視頻類似,只是直接從文件路徑中讀取。

void mThread::anayImages()
{
    QStringList files = m_Params.toStringList();
    for (auto file : files)
    {
        cv::Mat frame = cv::imread(file.toStdString().c_str());
        if (frame.empty() && !m_isRun)
            break;

        QString msg;
        delectDecoded(frame, msg);
        emit imageProcessed(MatToQImage(frame), msg); // 發(fā)射信號
        cv::waitKey(1000);
    }
}

四、二維碼檢測實現(xiàn)

1. 使用 OpenCV 進行檢測

在 delectDecoded() 方法中,利用 OpenCV 的 QRCodeDetector 類進行二維碼檢測和解碼,并將結(jié)果繪制到圖像中。

int mThread::delectDecoded(cv::Mat &image, QString &code)
{
    cv::Mat bbox, rectifiedImage;
    std::string data = qrDecoder.detectAndDecode(image, bbox, rectifiedImage);

???????    if (data.length() > 0)
    {
        code = QString::fromStdString(data); // 將結(jié)果返回
        std::vector<cv::Point> points;
        for (int i = 0; i < bbox.cols; i++)
        {
            points.push_back(cv::Point(static_cast<int>(bbox.at<cv::Point2f>(0, i).x), static_cast<int>(bbox.at<cv::Point2f>(0, i).y)));
        }
        for (size_t i = 0; i < points.size(); i++)
        {
            cv::line(image, points[i], points[(i + 1) % points.size()], cv::Scalar(0, 255, 0), 3); // 繪制綠色邊框
        }
        int minY = points[0].y;
        for (const auto &point : points) {
            minY = std::min(minY, point.y);
        }
        cv::putText(image, data, cv::Point(points[0].x, minY - 10), cv::FONT_HERSHEY_SIMPLEX, 0.7, cv::Scalar(0, 255, 0), 2); // 顯示二維碼信息
    }
    else
    {
        code = tc("未檢測到二維碼!");
    }

    return 0;
}

2. Mat 轉(zhuǎn) QImage

為了在 Qt 界面中顯示 OpenCV 的圖像,MatToQImage() 將 OpenCV 的 cv::Mat 轉(zhuǎn)換為 Qt 的 QImage。

五、多線程與信號槽

在本項目中,多線程通過信號與槽實現(xiàn)以下功能:

更新主界面狀態(tài):線程的運行狀態(tài)(如啟動和停止)通過 RuningState 信號通知主線程。

實時更新圖像和檢測結(jié)果:imageProcessed 信號傳遞處理后的圖像和二維碼信息,更新界面。

connect(mthread, &mThread::imageProcessed, this, &MainWindow::processImage);

???????void MainWindow::processImage(const QImage &image, const QString &msg)
{
    ui->lab_disp->setPixmap(QPixmap::fromImage(image).scaled(image.width() / 2, image.height() / 2)); // 顯示縮放后的圖像
    ui->lab_disData->setText(msg); // 顯示檢測到的信息
}

以上就是基于Qt和Opencv實現(xiàn)二維碼解析的詳細內(nèi)容,更多關(guān)于Qt Opencv二維碼解析的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 深入解讀C++中的右值引用

    深入解讀C++中的右值引用

    這里來帶大家深入解讀C++中的右值引用,右值引用是C++新標準中的重要特性,包括C++11中的引用折疊,首先還是先來看一下右值引用的概念:
    2016-05-05
  • C++實現(xiàn)簡易選課系統(tǒng)代碼分享

    C++實現(xiàn)簡易選課系統(tǒng)代碼分享

    這篇文章主要介紹了C++實現(xiàn)簡易選課系統(tǒng)及實現(xiàn)代碼的分享,具有一定的參考價值,需要的小伙伴可以參考一下,希望對你有所幫助
    2022-01-01
  • 實例講解C++設(shè)計模式編程中State狀態(tài)模式的運用場景

    實例講解C++設(shè)計模式編程中State狀態(tài)模式的運用場景

    這篇文章主要介紹了實例講解C++設(shè)計模式編程中State狀態(tài)模式的運用場景,文章最后的適用性部分則介紹了一些State模式善于處理的情況,需要的朋友可以參考下
    2016-03-03
  • 在Visual Studio中配置C++最新版netCDF庫的方法

    在Visual Studio中配置C++最新版netCDF庫的方法

    本文介紹在Windows電腦的Visual Studio軟件中,配置C++ 語言最新版netCDF庫的方法,文中通過圖文結(jié)合的形式介紹的非常詳細,具有一定的參考價值,需要的朋友可以參考下
    2024-03-03
  • C++模擬實現(xiàn)時間輪模式(推薦)

    C++模擬實現(xiàn)時間輪模式(推薦)

    文章介紹了時間輪(TimerWheel)的原理和實現(xiàn)方式,這是一種高效的定時器管理算法,常用于操作系統(tǒng)內(nèi)核,時間輪通過類似鐘表的機制管理定時任務(wù),每過一秒,秒針移動一格,觸發(fā)相應(yīng)任務(wù),感興趣的朋友跟隨小編一起看看吧
    2025-11-11
  • 詳解c++實現(xiàn)信號槽

    詳解c++實現(xiàn)信號槽

    這篇文章主要為大家介紹了c++實現(xiàn)信號槽,具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2021-12-12
  • set_new_handler(0)有什么用

    set_new_handler(0)有什么用

    本文主要介紹了set_new_handler(0)有什么用,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-08-08
  • C++實現(xiàn)LeetCode(113.二叉樹路徑之和之二)

    C++實現(xiàn)LeetCode(113.二叉樹路徑之和之二)

    這篇文章主要介紹了C++實現(xiàn)LeetCode(113.二叉樹路徑之和之二),本篇文章通過簡要的案例,講解了該項技術(shù)的了解與使用,以下就是詳細內(nèi)容,需要的朋友可以參考下
    2021-07-07
  • C++實現(xiàn)LeetCode(151.翻轉(zhuǎn)字符串中的單詞)

    C++實現(xiàn)LeetCode(151.翻轉(zhuǎn)字符串中的單詞)

    這篇文章主要介紹了C++實現(xiàn)LeetCode(151.翻轉(zhuǎn)字符串中的單詞),本篇文章通過簡要的案例,講解了該項技術(shù)的了解與使用,以下就是詳細內(nèi)容,需要的朋友可以參考下
    2021-07-07
  • C語言實現(xiàn)學(xué)生選課系統(tǒng)完整版

    C語言實現(xiàn)學(xué)生選課系統(tǒng)完整版

    這篇文章主要為大家詳細介紹了C語言實現(xiàn)學(xué)生選課系統(tǒng)的完整版,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-02-02

最新評論

海阳市| 洮南市| 巩义市| 绥阳县| 阳东县| 宁都县| 苍南县| 玉屏| 大姚县| 志丹县| 南溪县| 衡水市| 汽车| 广东省| 武邑县| 大石桥市| 江达县| 侯马市| 盖州市| 台安县| 明水县| 德保县| 于都县| 河池市| 广河县| 三河市| 馆陶县| 化德县| 池州市| 惠东县| 连江县| 文登市| 黑水县| 双流县| 天长市| 西乡县| 闵行区| 鄂托克旗| 镇巴县| 万安县| 晋城|