项目实战: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、单片机、软硬结合等等)持续更新中…(点击传送门)
需求
激光射击游戏,外设激光射击目标圆圈,计分游戏。
原理
使用OpenCV打开摄像头,识别圆圈,识别激光,判断激光点是否在圆圈内。
注意
需要摄像头,摄像头对准白色矩形区域,游戏钱需要先对摄像头进行手动校准,提供调整校准标定的功能,调整到圆圈和激光都可识别。
相关博客
《项目实战:Qt+OpenCV操作摄像头拍照、调节参数和视频录制》
《OpenCV开发笔记(一):OpenCV介绍、编译》
《OpenCV开发笔记(五):OpenCV读取与操作摄像头》
《OpenCV开发笔记(七):OpenCV基础图形绘制》
《OpenCV开发笔记(十):OpenCV图像颜色通道分离和图像颜色多通道混合》
《OpenCV开发笔记(二十一):算法基础之形态学滤波-膨胀》
《OpenCV开发笔记(二十二):算法基础之形态学滤波-腐蚀》
《OpenCV开发笔记(二十八):带你学习图像识别之阈值化》
《OpenCV开发笔记(三十六):红胖子8分钟带你深入了解缩放与图像金字塔(图文并茂+浅显易懂+程序源码)》
《OpenCV开发笔记(五十三):红胖子8分钟带你深入了解模板匹配识别(图文并茂+浅显易懂+程序源码)》
Demo:激光射击游戏 v1.0.0






下载地址
CSDN:https://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
项目实战:Qt+OpenCV激光射击游(识别激光、识别圆)的更多相关文章
- 项目实战:Qt+OpenCV大家来找茬(Qt抓图,穿透应用,识别左右图区别,框选区别,微调位置)
前言 本项目的出现理由只是笔者的一个念头,于是利用专业Qt和Opencv相关的知识开发一个辅助工具,本文章仅用于Qt和Opencv结合的学习. Demo演示效果 运行包下载地 ...
- 项目实战:Qt+Ffmpeg+OpenCV相机程序(打开摄像头、支持多种摄像头、分辨率调整、翻转、旋转、亮度调整、拍照、录像、回放图片、回放录像)
若该文为原创文章,未经允许不得转载原博主博客地址:https://blog.csdn.net/qq21497936原博主博客导航:https://blog.csdn.net/qq21497936/ar ...
- 项目实战:Qt手机模拟器拉伸旋转框架
若该文为原创文章,未经允许不得转载原博主博客地址:https://blog.csdn.net/qq21497936原博主博客导航:https://blog.csdn.net/qq21497936/ar ...
- Visual Studio 2015开发Qt项目实战经验分享(附项目示例源码)
Visual Studio 2015开发Qt项目实战经验分享(附项目示例源码) 转 https://blog.csdn.net/lhl1124281072/article/details/800 ...
- 【从零学习openCV】IOS7人脸识别实战
前言 接着上篇<IOS7下的人脸检測>,我们顺藤摸瓜的学习怎样在IOS7下用openCV的进行人脸识别,实际上非常easy,因为人脸检測部分已经完毕,剩下的无非调用openCV的方法对採集 ...
- 【大话QT之十六】使用ctkPluginFramework插件系统构建项目实战
"使用ctkPluginFramework插件系统构建项目实战",这篇文章是写博客以来最纠结的一篇文章. 倒不是由于技术都多么困难,而是想去描写叙述一个项目架构採用ctkPlugi ...
- QT新建空白项目-添加QT设计师界面类时出现的各种库无法导入识别
按照教材上先新建一个空的项目--添加Qt设计师界面类时 出现各种 库无法识别 解决方法: 在 .pro文件中加入一行 QT += widgets 去构建中先执行 qmake 然后再构建一下 ok了 ...
- QT5 QSS QML界面美化视频课程系列 QT原理 项目实战 C++1X STL
QT5 QSS QML界面美化视频课程系列 QT原理 项目实战 C++1X STL 课程1 C语言程序设计高级实用速成课程 基础+进阶+自学 课程2 C语言程序设计Windows GDI图形绘 ...
- 第二百五十二节,Bootstrap项目实战-首页
Bootstrap项目实战-首页 html <!DOCTYPE html> <html lang="zh-cn"> <head> <met ...
- 给缺少Python项目实战经验的人
我们在学习过程中最容易犯的一个错误就是:看的多动手的少,特别是对于一些项目的开发学习就更少了! 没有一个完整的项目开发过程,是不会对整个开发流程以及理论知识有牢固的认知的,对于怎样将所学的理论知识应用 ...
随机推荐
- [转帖]jmeter正则表达式应用-01篇
如图所示 1.先新建一个login的http请求,然后再login的请求下新增一个正则表达式提取器,增加一个查看结果树查看结果 假如后端接口返回的数据为"{'msg': 'login suc ...
- [转帖]Django系列3-Django常用命令
文章目录 一. Django常用命令概述 二. Django常用命令实例 2.1 help命令 2.2 version 2.3 check 2.4 startproject 2.5 startapp ...
- MySQL数据库页存储结构学习与了解
MySQL数据库页存储结构学习与了解 背景 MySQL总是出现奇奇怪怪的问题. 想着自己能够学习与提高一下. 最近看了很多文档.关于MySQL数据库相关的. 想着总结和提炼一下, 希望能够给未来的工作 ...
- [转帖]Windows版本vcenter server6.0的SSO密码重置
Windows版本的SSO重置与vCenter Server Appliance的重置类似 登录vcenter服务器,打开DOS窗口,输入 cd c:\Program Files\VMware\vCe ...
- [转帖]Redis命令详解:Keys
https://jackeyzhe.github.io/2018/09/22/Redis%E5%91%BD%E4%BB%A4%E8%AF%A6%E8%A7%A3%EF%BC%9AKeys/ 介绍完Re ...
- 【实践篇】最全的【DDD领域建模】小白学习手册(文末附资料)
导读 DDD领域建模被各个大小厂商提起并应用,而每个人都有自己的理解,本文就是针对小白,系统地讲解DDD到底是什么,解决了什么问题,及一些建议和实践.本文主要是思想的一种碰撞和分享,希望能对朋友们有所 ...
- XCODE IOS 静态链接库替换升级
XCODE 版本15.2. 一个很久需求没更新的IOS 应用,近来有新需求要开发. 拉下代码运行,出现了个BAD_ACCESS错误.出错的位置位于一个调用的第三方的.a静态库内部.因为调用代码并没有修 ...
- ABP vNext系列文章01---模块化
一.模块化应用 1.继承AbpModule 每个模块都应该定义一个模块类.定义模块类的最简单方法是创建一个派生自AbpModule的类,如下所示: 2.配置依赖注入和其他模块---ConfigSe ...
- 2.6 CE修改器:代码注入功能
从本关开始,各位会初步接触到CE的反汇编功能,这也是CE最强大的功能之一.在第6关的时候我们说到指针的找法,用基址定位动态地址.但这一关不用指针也可以进行修改,即使对方是动态地址,且功能更加强大.代码 ...
- 2.5 PE结构:导入表详细解析
导入表(Import Table)是Windows可执行文件中的一部分,它记录了程序所需调用的外部函数(或API)的名称,以及这些函数在哪些动态链接库(DLL)中可以找到.在Win32编程中我们会经常 ...