项目实战:Qt+OpenCV大家来找茬(Qt抓图,穿透应用,识别左右图区别,框选区别,微调位置)
前言
本项目的出现理由只是笔者的一个念头,于是利用专业Qt和Opencv相关的知识开发一个辅助工具,本文章仅用于Qt和Opencv结合的学习。
  
  
  
  
  CSDN粉丝0积分下载地址:https://download.csdn.net/download/qq21497936/85372782
  QQ群下载地址:1047134658(点击“文件”搜索“findTheDifference”,群内与博文同步更新)
  CSDN下载地址:https://download.csdn.net/download/qq21497936/85372767
  (注意:源码本博客后面都有,若是想一步到位,下载这个,源码编译版本为Qt5.9.x mingw32 + openCV3.4.10)
- 应用程序可将某Q游戏界面套入内部区域,游戏方便操作;
- 抓图区域调整,可通过右上角区域,调整区域1和区域2的位置;
- 位置微调功能,点击按钮可像对应方向微调一个像素;
- 识别不同,调用opencv算法,识别不同处在游戏图上绘制显示区域;
- 游戏界面区域操作焦点为游戏界面;
- 可清空已经绘制的区域;
- Qt窗口部分透明
 《Qt实用技巧:实现不规则窗口的鼠标消息穿透,包括穿透到桌面和穿透到父窗口》;
- Qt窗口透明区域鼠标穿透
 《Qt实用技巧:使用非透明窗体鼠标穿透到桌面的设置方法》;
- Qt窗口置顶
 《Qt实用技巧:Qt窗口置顶》;
- Qt绘图
 《Qt开发技术:Qt绘图系统(一)绘图系统介绍》
 《Qt开发技术:Qt绘图系统(二)QPainter详解》;
- Qt双窗口叠加(底窗口+透明窗口层)
 《Qt实用技巧:实现窗口透明的五种方法》中的方法五;
- QLabel,QGroupBox,QSpinBox,QPushButton控件的使用
- Qt截取屏幕
 《Qt实用技巧:截屏功能的实现》
- OpenCV开发环境的搭建
 《OpenCV开发笔记(〇):使用mingw530_32编译openCV3.4.1源码,搭建Qt5.9.3的openCV开发环境》
- OpenCV中的cv::Mat
 《OpenCV开发笔记(三):OpenCV图像的概念和基本操作》
- OpenCV中QImage转换为cv::Mat
- OpenCV灰度化
 《OpenCV开发笔记(六):OpenCV基础数据结构、颜色转换函数和颜色空间》
- OpenCV阈值化
 《OpenCV开发笔记(二十八):带你学习图像识别之阈值化》
- OpenCV的中值滤波
 《OpenCV开发笔记(十八):算法基础之非线性滤波-中值滤波》
- OpenCV的闭运算
 《OpenCV开发笔记(二十四):算法基础之形态学滤波-闭运算》
- OpenCV的寻找边界
 《OpenCV开发笔记(二十八):带你学习图像识别之阈值化》
- OpenCv的最小矩形
 《OpenCV开发笔记(五十六):红胖子8分钟带你深入了解多种图形拟合逼近轮廓(图文并茂+浅显易懂+程序源码)》
  项目的环境为Qt5.9.3 mingw32版本,使用QtCreator开发,配合mingw32版本的Opencv3.4.10,下图左侧为项目结构,右侧为实际文件夹部署结构。
  
该类的主要作用:
- 覆盖在游戏窗口上
- 全部透明窗口用以当作游戏界面上的画布
- 对鼠标消息穿透(无法点击中)
- 识别出后绘制标记处不同的区域
  为自动生成默认的,没有任何改动。
  
  一共绘制两类图形,一类是框出抓取图的界面,一类是识别出后的区域,定义两个缓存变量,用以绘制对应的区域矩形。
#ifndef DRAWWIDGET_H
#define DRAWWIDGET_H
#include <QWidget>
namespace Ui {
class DrawWidget;
}
class DrawWidget : public QWidget
{
    Q_OBJECT
public:
    explicit DrawWidget(QWidget *parent = 0);
    ~DrawWidget();
public:
    void setRect(int x, int y, int width, int height);
    void setRect2(int x, int y, int width, int height);
    void clearListRect();
    void setListRect(QList<QRect> listRect);
protected:
    void initControl();
protected:
    void paintEvent(QPaintEvent *event);
protected:
    void drawSelectRect(QPainter *painter);
    void drawListRect(QPainter *painter);
private:
    Ui::DrawWidget *ui;
private:
    QColor _colorRect;
    QRect _rect;
    QRect _rect2;
    QList<QRect> _listRect;
};
#endif // DRAWWIDGET_H
#include "DrawWidget.h"
#include "ui_DrawWidget.h"
#include <QPainter>
#include <windows.h>
#include <QDebug>
#include <QDateTime>
//#define LOG qDebug()<<__FILE__<<__LINE__
//#define LOG qDebug()<<__FILE__<<__LINE__<<__FUNCTION__
//#define LOG qDebug()<<__FILE__<<__LINE__<<QThread()::currentThread()
//#define LOG qDebug()<<__FILE__<<__LINE__<<QDateTime::currentDateTime().toString("yyyy-MM-dd")
#define LOG qDebug()<<__FILE__<<__LINE__<<QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss:zzz")
DrawWidget::DrawWidget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::DrawWidget),
    _colorRect(Qt::red)
{
    ui->setupUi(this);
    setWindowFlag(Qt::FramelessWindowHint);
    setAttribute(Qt::WA_TranslucentBackground);
    setAttribute(Qt::WA_TransparentForMouseEvents);
    initControl();
}
DrawWidget::~DrawWidget()
{
    delete ui;
}
void DrawWidget::setRect(int x, int y, int width, int height)
{
    _rect.setRect(x, y, width, height);
}
void DrawWidget::setRect2(int x, int y, int width, int height)
{
    _rect2.setRect(x, y, width, height);
    LOG << _rect << _rect2;
}
void DrawWidget::clearListRect()
{
    _listRect.clear();
    update();
}
void DrawWidget::setListRect(QList<QRect> listRect)
{
    _listRect = listRect;
    update();
}
void DrawWidget::initControl()
{
    // 置顶
    ::SetWindowPos(HWND(this->winId()), HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW);
}
void DrawWidget::paintEvent(QPaintEvent *event)
{
    QPainter painter(this);
    drawSelectRect(&painter) 
                    
                     
                    
                 
                    
                