項目實戰:Qt+OpenCV激光射擊遊戲(識別激光、識別圓)

若該文爲原創文章,未經允許不得轉載
原博主博客地址:https://blog.csdn.net/qq21497936
原博主博客導航:https://blog.csdn.net/qq21497936/article/details/102478062
本文章博客地址:https://blog.csdn.net/qq21497936/article/details/106647346
紅胖子(紅模仿)的博文大全:開發技術集合(包含Qt實用技術、樹莓派、三維、OpenCV、OpenGL、ffmpeg、OSG、單片機、軟硬結合等等)持續更新中…(點擊傳送門)

Qt開發專欄:項目實戰(點擊傳送門)

OpenCV開發專欄(點擊傳送門)


需求

  激光射擊遊戲,外設激光射擊目標圓圈,計分遊戲。


原理

  使用OpenCV打開攝像頭,識別圓圈,識別激光,判斷激光點是否在圓圈內。


注意

  需要攝像頭,攝像頭對準白色矩形區域,遊戲錢需要先對攝像頭進行手動校準,提供調整校準標定的功能,調整到圓圈和激光都可識別。


相關博客

  項目實戰:Qt+OpenCV操作攝像頭拍照、調節參數和視頻錄製
  《OpenCV開發筆記(一):OpenCV介紹、編譯
  《OpenCV開發筆記(五):OpenCV讀取與操作攝像頭
  《OpenCV開發筆記(七):OpenCV基礎圖形繪製
  《OpenCV開發筆記(十):OpenCV圖像顏色通道分離和圖像顏色多通道混合
  《OpenCV開發筆記(二十一):算法基礎之形態學濾波-膨脹
  《OpenCV開發筆記(二十二):算法基礎之形態學濾波-腐蝕
  《OpenCV開發筆記(二十八):帶你學習圖像識別之閾值化
  《OpenCV開發筆記(三十六):紅胖子8分鐘帶你深入瞭解縮放與圖像金字塔(圖文並茂+淺顯易懂+程序源碼)
  《OpenCV開發筆記(五十三):紅胖子8分鐘帶你深入瞭解模板匹配識別(圖文並茂+淺顯易懂+程序源碼)


Demo:激光射擊遊戲 v1.0.0

  在這裏插入圖片描述
  在這裏插入圖片描述
  在這裏插入圖片描述
  在這裏插入圖片描述
  在這裏插入圖片描述
  在這裏插入圖片描述


下載地址

  CSDNhttps://download.csdn.net/download/qq21497936/12507420
  QQ羣:1047134658(點擊“文件”搜索“shootGame”,羣內與博文同步更新所有可開源的源碼模板)


核心代碼

#ifndef SHOOTGAMEWIDGET_H
#define SHOOTGAMEWIDGET_H

#include <QWidget>
#include "OpenCVManager.h"
#include <QTimer>
#include <QThread>

namespace Ui {
class ShootGameWidget;
}

class ShootGameWidget : public QWidget
{
    Q_OBJECT

public:
    explicit ShootGameWidget(QWidget *parent = 0);
    ~ShootGameWidget();

protected slots:
    void slot_captureOneFrame(cv::Mat mat);
    bool slot_recognize(cv::Mat mat, bool show = false);
    void slot_timeOut();

private slots:
    void on_pushButton_start_clicked();
    void on_pushButton_out_clicked();

    void on_pushButton_startCameraTest_clicked();
    void on_pushButton_stopCameraTest_clicked();

    void on_pushButton_add1_clicked();
    void on_pushButton_dec1_clicked();
    void on_pushButton_add2_clicked();
    void on_pushButton_dec2_clicked();
    void on_pushButton_add3_clicked();
    void on_pushButton_dec3_clicked();

private:
    void paintEvent(QPaintEvent *event);
    void timerEvent(QTimerEvent *event);

private:
    Ui::ShootGameWidget *ui;
    OpenCVManager *_pOpenCVManager;
    QThread *_pOpenCVManagerThread;
    cv::Mat _srcMat;
    QImage _srcImage;
    int _r;
    int _penWidth;
    cv::Mat _circleMat;
    cv::Mat _dotMat;
    cv::Mat _dot2Mat;
    cv::Mat _dot3Mat;
    cv::Mat _dot4Mat;
    cv::Mat _dot5Mat;
    cv::Mat _dot6Mat;
    cv::Mat _dot7Mat;
    int _timerId;
    double _f;
    int _margin;
    int _count;
    int _totalTime;         // 總時間,默認60s
    int _currentTime;       // 當前時間
    bool _running;          // 是否遊戲開始
    QPoint _centerPoint;    // 刷新圓圈的位置
    bool _hitFlag;          // 是否擊中標誌,每次刷新位置,設置false,判斷是否第一次擊中用於計分
    int _score;             // 得分
    QTimer *_pTimer;        // 定時器,定時減少秒數
    bool _result;           // 標記是否打完出結果
};
#endif // SHOOTGAMEWIDGET_H
void ShootGameWidget::on_pushButton_start_clicked()
{
    if(!_pOpenCVManager->startCapture(0, 800, 600))
    {
        QMessageBox::information(0, "錯誤", "檢測攝像頭失敗");
        return;
    }
    ui->label_title->setVisible(false);
    ui->pushButton_start->setVisible(false);
    ui->pushButton_out->setVisible(false);
    ui->groupBox->setVisible(false);
    _hitFlag = false;
    _score = 0;
    _currentTime = _totalTime;
    _running = true;
    _result = false;
    _pTimer->start();
}
void ShootGameWidget::paintEvent(QPaintEvent *event)
{
    if(ui->pushButton_stopCameraTest->isEnabled() || _running)
    {
        QPainter painter(this);
        painter.fillRect(rect(), Qt::black);
        painter.setPen(QPen(Qt::white, 1));
        painter.drawRect(_margin,
                         _margin,
                         rect().width() - _margin * 2,
                         rect().height() - _margin * 2);
        QPen pen = painter.pen();
        pen.setWidth(10);
        pen.setColor(Qt::green);
        painter.setPen(pen);
        painter.drawEllipse(_centerPoint, _r/2, _r/2);
//        painter.setPen(QPen(Qt::red, 10));
//        painter.drawPoint(_centerPoint);
        if(_running)
        {
            painter.setPen(QPen(Qt::white, 1));
            painter.drawText(300, 50, QString("得分: %1").arg(_score));
            painter.drawText(500, 50, QString("倒計時: %1").arg(_currentTime));
            if(_hitFlag)
            {
                painter.drawText(700, 50, QString("已擊中"));
            }else{
                painter.drawText(700, 50, QString("未擊中"));
            }
        }
    }
    if(_result)
    {
        QPainter painter(this);
        painter.setPen(QPen(Qt::black, 4));
        QFont font = painter.font();
        font.setPixelSize(64);
        painter.setFont(font);
        painter.drawText(rect(), Qt::AlignCenter, QString("遊戲結束,您的得分爲 %1 !!!").arg(_score));
    }
}
void ShootGameWidget::slot_timeOut()
{
    if(_running)
    {
        _currentTime--;
        if(_currentTime == 0)
        {
            if(!_pOpenCVManager->stopCapture())
            {
            }
            ui->label_title->setVisible(true);
            ui->pushButton_start->setVisible(true);
            ui->pushButton_out->setVisible(true);
            ui->groupBox->setVisible(true);
            _hitFlag = false;
            _currentTime = _totalTime;
            _running = false;
            _pTimer->stop();
            _result = true;
        }
        update();
    }
}

原博主博客地址:https://blog.csdn.net/qq21497936
原博主博客導航:https://blog.csdn.net/qq21497936/article/details/102478062
本文章博客地址:https://blog.csdn.net/qq21497936/article/details/106647346

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章