若该文为原创文章,转载请注明出处
本文章博客地址https://hpzwl.blog.csdn.net/article/details/124768637
红胖子(红模仿)的博文大全:开发技术集合(包含Qt实用技术、树莓派、三维、OpenCV、OpenGL、ffmpeg、OSG、单片机、软硬结合等等)持续更新中…(点击传送门)

Qt开发专栏:项目实战(点击传送门)

OpenCV开发专栏(点击传送门)

前言

  本项目的出现理由只是笔者的一个念头,于是利用专业Qt和Opencv相关的知识开发一个辅助工具,本文章仅用于Qt和Opencv结合的学习。

Demo演示效果

  
  
  
  

运行包下载地址(供测试学习)

  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开发技术:Qt绘图系统(二)QPainter详解》;
  • Qt双窗口叠加(底窗口+透明窗口层)
      《Qt实用技巧:实现窗口透明的五种方法》中的方法五;
  • QLabel,QGroupBox,QSpinBox,QPushButton控件的使用
  • Qt截取屏幕
      《Qt实用技巧:截屏功能的实现》

OpenCV技术点

  • 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,下图左侧为项目结构,右侧为实际文件夹部署结构。
  

Qt代码:DrawWdget

  该类的主要作用:

  • 覆盖在游戏窗口上
  • 全部透明窗口用以当作游戏界面上的画布
  • 对鼠标消息穿透(无法点击中)
  • 识别出后绘制标记处不同的区域

Ui界面

  为自动生成默认的,没有任何改动。
  
  一共绘制两类图形,一类是框出抓取图的界面,一类是识别出后的区域,定义两个缓存变量,用以绘制对应的区域矩形。

DrawWidegt.h

#ifndef DRAWWIDGET_H
#define DRAWWIDGET_H#include <QWidget>namespace Ui {class DrawWidget;
}class DrawWidget : public QWidget
{Q_OBJECTpublic: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

DrawWidget.cpp

#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);drawListRect(&painter);
}void DrawWidget::drawSelectRect(QPainter *painter)
{painter->save();painter->setPen(QPen(_colorRect, 4));painter->drawRect(_rect);painter->drawRect(_rect2);painter->restore();
}void DrawWidget::drawListRect(QPainter *painter)
{painter->save();painter->setPen(QPen(Qt::white, 2));for(int index = 0; index < _listRect.size(); index++){painter->drawRect(_rect.x() + _listRect.at(index).x(),_rect.y() + _listRect.at(index).y(),_listRect.at(index).width(),_listRect.at(index).height());}painter->setPen(QPen(Qt::blue, 2));for(int index = 0; index < _listRect.size(); index++){painter->drawRect(_rect2.x() + _listRect.at(index).x(),_rect2.y() + _listRect.at(index).y(),_listRect.at(index).width(),_listRect.at(index).height());}painter->restore();
}

Qt代码:FindDifferenceWidget

  该类的主要作用:

  • 作为主窗口提供一个套入找茬游戏界面的区域;
  • 提供可以动态选取抓取区域的控件;
  • 提供微调控件,微调应用窗口,并且让DrawWidget窗口与透明区域位置同步改变;
  • 提供识别触发按钮,将识别结果反馈到DrawWidget;
  • 清空按钮,将识别的结果进行清空,也就是删除识别结果的矩形;

Ui界面

  

FindDifferenceWidget.h

#ifndef FINDDIFFERENCEWIDGET_H
#define FINDDIFFERENCEWIDGET_H#include <QWidget>
#include <QPainter>
#include <QRect>
#include <QRegion>
#include <QList>
#include "FindDifferenceManager.h"
#include "DrawWidget.h"
#include <QElapsedTimer>namespace Ui {class FindDifferenceWidget;
}class FindDifferenceWidget : public QWidget
{Q_OBJECTpublic:explicit FindDifferenceWidget(QWidget *parent = 0);~FindDifferenceWidget();protected:void initControl();void updateGameRect();protected slots:void slot_initControl();protected:void paintEvent(QPaintEvent *event);void resizeEvent(QResizeEvent *event);void moveEvent(QMoveEvent *event);void closeEvent(QCloseEvent *event);protected slots:void slot_valueChanged(int value);protected slots:void slot_findResult(bool result, QList<QRect> listRect = QList<QRect>());private slots:void on_pushButton_do_clicked();void on_pushButton_up_clicked();void on_pushButton_left_clicked();void on_pushButton_right_clicked();void on_pushButton_down_clicked();void on_pushButton_clear_clicked();private:Ui::FindDifferenceWidget *ui;private:FindDifferenceManager *_pFindDifferenceManager;QRect _rectGame;QRect _rectApplication;int _captionHeigh;int _margin;DrawWidget *_pDrawWidget;
};#endif // FINDDIFFERENCEWIDGET_H

FindDifferenceWidget.cpp

#include "FindDifferenceWidget.h"
#include "ui_FindDifferenceWidget.h"#include <windows.h>
#include <QApplication>
#include <QDesktopWidget>
#include <QScreen>
#include <QTimer>#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")FindDifferenceWidget::FindDifferenceWidget(QWidget *parent) :QWidget(parent),ui(new Ui::FindDifferenceWidget),_pFindDifferenceManager(0),_pDrawWidget(0)
{ui->setupUi(this);QString version = "v1.0.0";setWindowTitle(QString("大家来找茬(仅供学习Qt+OpenCV实战项目) Demo %1(作者:长沙红胖子 QQ:21497936 WX:15173255813 blog:hpzwl.blog.csdn.net").arg(version));resize(1230, 785);initControl();QTimer::singleShot(0, this, SLOT(slot_initControl()));
}FindDifferenceWidget::~FindDifferenceWidget()
{delete ui;
}void FindDifferenceWidget::initControl()
{// 置顶::SetWindowPos(HWND(this->winId()), HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW);// 识别类_pFindDifferenceManager = new FindDifferenceManager();connect(_pFindDifferenceManager, SIGNAL(signal_findResult(bool,QList<QRect>)),this, SLOT(slot_findResult(bool,QList<QRect>)));// 初始化_captionHeigh = 26;_margin = 3;updateGameRect();_pDrawWidget = new DrawWidget();_pDrawWidget->show();connect(ui->spinBox_image1X, SIGNAL(valueChanged(int)),this, SLOT(slot_valueChanged(int)));connect(ui->spinBox_image1Y, SIGNAL(valueChanged(int)),this, SLOT(slot_valueChanged(int)));connect(ui->spinBox_image1Width, SIGNAL(valueChanged(int)),this, SLOT(slot_valueChanged(int)));connect(ui->spinBox_image1Height, SIGNAL(valueChanged(int)),this, SLOT(slot_valueChanged(int)));connect(ui->spinBox_image2X, SIGNAL(valueChanged(int)),this, SLOT(slot_valueChanged(int)));connect(ui->spinBox_image2Y, SIGNAL(valueChanged(int)),this, SLOT(slot_valueChanged(int)));connect(ui->spinBox_image2Width, SIGNAL(valueChanged(int)),this, SLOT(slot_valueChanged(int)));connect(ui->spinBox_image2Height, SIGNAL(valueChanged(int)),this, SLOT(slot_valueChanged(int)));_pDrawWidget->setRect(ui->spinBox_image1X->value(),ui->spinBox_image1Y->value(),ui->spinBox_image1Width->value(),ui->spinBox_image1Height->value());_pDrawWidget->setRect2(ui->spinBox_image2X->value(),ui->spinBox_image2Y->value(),ui->spinBox_image2Width->value(),ui->spinBox_image2Height->value());}void FindDifferenceWidget::updateGameRect()
{_rectApplication = QRect(-_margin,-_captionHeigh,rect().width() + _margin*2,rect().height() + _captionHeigh + _margin);_rectGame = QRect(_margin, rect().height() - _margin - 780, 1032, 780);
}void FindDifferenceWidget::slot_initControl()
{_pDrawWidget->setGeometry(ui->frame_mask->mapToGlobal(QPoint(0, 0)).x(),ui->frame_mask->mapToGlobal(QPoint(0, 0)).y(),ui->frame_mask->width(),ui->frame_mask->height());}void FindDifferenceWidget::paintEvent(QPaintEvent *event)
{#if 1QRegion r1(_rectApplication);QRegion r2(_rectGame);QRegion r3 = r1 - r2;setMask(r3);
#endifQWidget::paintEvent(event);
}void FindDifferenceWidget::resizeEvent(QResizeEvent *event)
{// 初始化updateGameRect();if(_pDrawWidget){_pDrawWidget->setGeometry(ui->frame_mask->mapToGlobal(QPoint(0, 0)).x(),ui->frame_mask->mapToGlobal(QPoint(0, 0)).y(),ui->frame_mask->width(),ui->frame_mask->height());}
}void FindDifferenceWidget::moveEvent(QMoveEvent *event)
{if(_pDrawWidget){_pDrawWidget->setGeometry(ui->frame_mask->mapToGlobal(QPoint(0, 0)).x(),ui->frame_mask->mapToGlobal(QPoint(0, 0)).y(),ui->frame_mask->width(),ui->frame_mask->height());}LOG << geometry();
}void FindDifferenceWidget::closeEvent(QCloseEvent *event)
{_pDrawWidget->hide();_pDrawWidget->deleteLater();
}void FindDifferenceWidget::slot_valueChanged(int value)
{_pDrawWidget->setRect(ui->spinBox_image1X->value(),ui->spinBox_image1Y->value(),ui->spinBox_image1Width->value(),ui->spinBox_image1Height->value());_pDrawWidget->setRect2(ui->spinBox_image2X->value(),ui->spinBox_image2Y->value(),ui->spinBox_image2Width->value(),ui->spinBox_image2Height->value());_pDrawWidget->update();QSpinBox *pSpinBox = dynamic_cast<QSpinBox *>(sender());if(pSpinBox == ui->spinBox_image1Width){ui->spinBox_image2Width->setValue(value);}else if(pSpinBox == ui->spinBox_image2Width){ui->spinBox_image1Width->setValue(value);}else if(pSpinBox == ui->spinBox_image1Height){ui->spinBox_image2Height->setValue(value);}else if(pSpinBox == ui->spinBox_image2Height){ui->spinBox_image1Height->setValue(value);}
}void FindDifferenceWidget::slot_findResult(bool result, QList<QRect> listRect)
{if(result){LOG << listRect;_pDrawWidget->setListRect(listRect);}
}void FindDifferenceWidget::on_pushButton_do_clicked()
{_pDrawWidget->clearListRect();QElapsedTimer elapsedTimer;elapsedTimer.start();while(elapsedTimer.elapsed() < 500){qApp->processEvents();}QScreen * pScreen = QApplication::primaryScreen();QImage gameImage = pScreen->grabWindow(QApplication::desktop()->winId(),ui->frame_mask->mapToGlobal(QPoint(0, 0)).x(),ui->frame_mask->mapToGlobal(QPoint(0, 0)).y(),ui->frame_mask->width(),ui->frame_mask->height()).toImage();QImage image1 = gameImage.copy(ui->spinBox_image1X->value(),ui->spinBox_image1Y->value(),ui->spinBox_image1Width->value(),ui->spinBox_image1Height->value());QImage image2 = gameImage.copy(ui->spinBox_image2X->value(),ui->spinBox_image2Y->value(),ui->spinBox_image2Width->value(),ui->spinBox_image2Height->value());_pFindDifferenceManager->slot_findDiffrence(image1, image2);
}void FindDifferenceWidget::on_pushButton_up_clicked()
{setGeometry(geometry().x(), geometry().y() - 1, geometry().width(), geometry().height());
}void FindDifferenceWidget::on_pushButton_left_clicked()
{setGeometry(geometry().x() - 1, geometry().y(), geometry().width(), geometry().height());
}void FindDifferenceWidget::on_pushButton_right_clicked()
{setGeometry(geometry().x() + 1, geometry().y(), geometry().width(), geometry().height());
}void FindDifferenceWidget::on_pushButton_down_clicked()
{setGeometry(geometry().x(), geometry().y() + 1, geometry().width(), geometry().height());
}void FindDifferenceWidget::on_pushButton_clear_clicked()
{_pDrawWidget->setListRect(QList<QRect>());
}

OpenCV代码:FindDifferenceManager

  识别不同处代码类功能:

  • 引入OpenCV头文件和库文件
  • 提供接口输入2个同样大小的矩形、阈值和能识别的最小矩形。
  • 核心算法:先灰度图->阈值化->寻找边界->识别最小矩形
      (最开始算法进行了滤波,闭运算,因为实际有可能存在两幅图截屏就有色差导致灰度图色差小,实际有可能原图色差较小导致灰度色差较小,实际有可能不同的点较少导致滤波去掉了这些点,以上三种经过测试都是存在的)。

FindDifferenceManager.h

#ifndef FINDDIFFERENCEMANAGER_H
#define FINDDIFFERENCEMANAGER_H#include <QObject>
#include <QImage>// opencv
#include "opencv/highgui.h"
#include "opencv/cxcore.h"
#include "opencv2/core/core.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/opencv.hpp"
#include "opencv2/xphoto.hpp"
#include "opencv2/dnn/dnn.hpp"
// opencv_contrib
#include <opencv2/xphoto.hpp>
#include <opencv2/ximgproc.hpp>
#include <opencv2/calib3d.hpp>
#include <opencv2/features2d.hpp>
#include <opencv2/xfeatures2d.hpp>
#include <opencv2/xfeatures2d/nonfree.hpp>class FindDifferenceManager : public QObject
{Q_OBJECT
public:explicit FindDifferenceManager(QObject *parent = 0);private:bool getRunning() const;signals:void signal_findResult(bool result, QList<QRect> listRect = QList<QRect>());public slots:void slot_start();void slot_stop();public slots:void slot_findDiffrence(QImage image, QImage image2, int thresh = 20, QRect minRect = QRect(0, 0, 4, 4));protected:cv::Mat image2Mat(QImage image);private:bool _running;
};#endif // FINDDIFFERENCEMANAGER_H

FindDifferenceManager.cpp

#include "FindDifferenceManager.h"
#include <QTimer>#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")FindDifferenceManager::FindDifferenceManager(QObject *parent): QObject(parent),_running(false)
{qRegisterMetaType<QList<QRect>>("QList<QRect> ");
}bool FindDifferenceManager::getRunning() const
{return _running;
}void FindDifferenceManager::slot_start()
{if(_running){LOG << "Failed to" << __FUNCTION__ << ", it's already running.";return;}_running = true;
}void FindDifferenceManager::slot_stop()
{if(!_running){LOG << "Failed to" << __FUNCTION__ << ", it's not running.";return;}_running = false;
}void FindDifferenceManager::slot_findDiffrence(QImage image, QImage image2, int thresh, QRect minRect)
{QList<QRect> listRect;// 将QImage转换为cv::Matcv::Mat srcMat = image2Mat(image);cv::Mat srcMat2 = image2Mat(image2);if ((srcMat.rows != srcMat2.rows) || (srcMat.cols != srcMat2.cols)){emit signal_findResult(false);}cv::Mat srcMatGray;cv::Mat srcMat2Gray;// 转灰度图cv::cvtColor(srcMat, srcMatGray, cv::COLOR_BGR2GRAY);cv::cvtColor(srcMat2, srcMat2Gray, cv::COLOR_BGR2GRAY);//    cv::imshow("1", srcMatGray);
//    cv::imshow("2", srcMat2Gray);cv::Mat diffMatGray;// 图1减去图2:查看差异(灰度,可能差距不大,0-255, 0 1 2 3差距小看不出)cv::subtract(srcMatGray, srcMat2Gray, diffMatGray, cv::Mat(), CV_16SC1);// 绝对值(有负数,变正数)
//    cv::imshow("3", diffMatGray);cv::Mat diffAbsMatGray = cv::abs(diffMatGray);// 改变位深(归一化试过,但是可能存在0和255,导致漏掉一些)diffAbsMatGray.convertTo(diffAbsMatGray, CV_8UC1, 1, 0);
//    cv::imshow("4", diffAbsMatGray);#if 0// 整个像素降低5个点的误差(色差)for(int row = 0; row < diffAbsMatGray.rows; row++){for( int col = 0; col < diffAbsMatGray.cols; col++){if(diffAbsMatGray.at<uchar>(row, col) < 3){diffAbsMatGray.at<uchar>(row, col) = 0;}else{diffAbsMatGray.at<uchar>(row, col) = diffAbsMatGray.at<uchar>(row, col) - 5;}}}
#endifcv::Mat threshMat;//阈值处理cv::threshold(diffAbsMatGray, threshMat, thresh, 255, cv::THRESH_BINARY);
//    cv::imshow("5", threshMat);cv::Mat mdianMat;
#if 0//中值滤波cv::medianBlur(threshMat, mdianMat, 3);cv::imshow("6", mdianMat);
#elsemdianMat = threshMat.clone();
#endifcv::Mat closeMat;
#if 0// 闭运算: 用拟合小裂缝,消除小型黑洞,并且在平滑较大物体的边界的同时不明显改变其面积。cv::Mat kernel = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(3, 3), cv::Point(-1, -1));cv::morphologyEx(mdianMat, closeMat, cv::MORPH_CLOSE, kernel, cv::Point(-1, -1), 2, cv::BORDER_REPLICATE);
#elsecloseMat = mdianMat.clone();
#endif
//    cv::imshow("7", closeMat);// 寻找边界std::vector<std::vector<cv::Point>> contours;std::vector<cv::Vec4i> hierarchy;cv::findContours(closeMat,contours,hierarchy,CV_RETR_EXTERNAL,CV_CHAIN_APPROX_SIMPLE,cv::Point(0, 0));std::vector<std::vector<cv::Point>> contoursPoly(contours.size());for(int index = 0; index < contours.size(); index++){cv::approxPolyDP(cv::Mat(contours[index]), contoursPoly[index], 5, true);cv::Rect rect = cv::boundingRect(cv::Mat(contoursPoly[index]));#if 0// 小于最小矩形则忽略if(rect.width < minRect.width() || rect.height < minRect.height()){continue;}
#endiflistRect.append(QRect(rect.x, rect.y, rect.width, rect.height));
//        cv::rectangle(srcMat, rect, cv::Scalar(0, 255, 0), 2);
//        cv::rectangle(srcMat2, rect, cv::Scalar(0, 255, 0), 2);}
//    cv::imshow("8", srcMat2);//    cv::waitKey(0);emit signal_findResult(true, listRect);
}cv::Mat FindDifferenceManager::image2Mat(QImage image)
{cv::Mat mat;switch(image.format()){case QImage::Format_ARGB32:case QImage::Format_RGB32:case QImage::Format_ARGB32_Premultiplied:mat = cv::Mat(image.height(), image.width(), CV_8UC4, (void*)image.constBits(), image.bytesPerLine());cv::cvtColor(mat, mat, CV_BGRA2BGR);break;case QImage::Format_RGB888:mat = cv::Mat(image.height(), image.width(), CV_8UC3, (void*)image.constBits(), image.bytesPerLine());cv::cvtColor(mat, mat, CV_BGR2RGB);break;case QImage::Format_Indexed8:case QImage::Format_Grayscale8:mat = cv::Mat(image.height(), image.width(), CV_8UC1, (void*)image.constBits(), image.bytesPerLine());break;default:qDebug() << __FILE__ << __LINE__ << "error to image2Mat !!!  imge.format =" << image.format();}return mat;
}

若该文为原创文章,转载请注明出处
本文章博客地址https://hpzwl.blog.csdn.net/article/details/124768637

项目实战:Qt+OpenCV大家来找茬(Qt抓图,穿透应用,识别左右图区别,框选区别,微调位置)相关推荐

  1. 找茬小程序源码、看图找不同小程序,前端+后端+教程,微信小程序游戏一起来找茬,全网首发一款可以完美运营的找茬小程序源码

    演示小程序搜[最强脑洞I全民烧脑] 一共有2510关, 达到高级后会随机出现关卡: 一共7个能量, 每闯关一次扣除一个能量值, 看激励视频可以获得一个能量值: 金币获取: 段位升级 或者 观看激励视频 ...

  2. 【优秀课设】基于OpenCV的Python人脸识别、检测、框选(遍历目录下所有照片依次识别 视频随时标注)

    基于OpenCV的Python人脸识别.检测.框选 (遍历目录下所有照片依次识别 视频随时标注) 移步: https://blog.csdn.net/weixin_53403301/article/d ...

  3. 【项目实战课】NLP入门第1课,人人免费可学,基于TextCNN的新闻文本分类实战...

    欢迎大家来到我们的项目实战课,本期内容是<基于TextCNN的新闻文本分类实战>. 所谓项目课,就是以简单的原理回顾+详细的项目实战的模式,针对具体的某一个主题,进行代码级的实战讲解,可以 ...

  4. 【CV冬季划】终极进阶,超30个项目实战+3本书+3年知识星球

    大家好,今天正式发布2022年有三AI-CV冬季划,这是我们最高等级的CV季划小组,表示对参与者有更高的技术要求.在这个小组里,我们不再去系统性地学习基础知识,而是假设大家已经有了非常好的基础功底,我 ...

  5. 【项目实战课】微信小程序图像识别模型前后端部署实战

    欢迎大家来到我们的项目实战课,本期内容是<微信小程序图像识别模型前后端部署实战>.所谓项目实战课,就是以简单的原理回顾+详细的项目实战的模式,针对具体的某一个主题,进行代码级的实战讲解. ...

  6. 【项目实战课】基于Pytorch的SRGAN图像超分辨实战

    欢迎大家来到我们的项目实战课,本期内容是<基于Pytorch的SRGAN图像超分辨实战>.所谓项目实战课,就是以简单的原理回顾+详细的项目实战的模式,针对具体的某一个主题,进行代码级的实战 ...

  7. 【项目实战课】人人免费可学!基于Pytorch的图像分类简单任务数据增强实战

    欢迎大家来到我们的项目实战课,本期内容是<基于Pytorch的图像分类简单任务数据增强实战>.所谓项目实战课,就是以简单的原理回顾+详细的项目实战的模式,针对具体的某一个主题,进行代码级的 ...

  8. 【项目实战课】基于Pytorch的UGATIT人脸动漫风格化实战

    欢迎大家来到我们的项目实战课,本期内容是<基于Pytorch的UGATIT人脸动漫风格化实战>.所谓项目课,就是以简单的原理回顾+详细的项目实战的模式,针对具体的某一个主题,进行代码级的实 ...

  9. 【项目实战课】基于Pytorch的InceptionNet花卉图像分类实战

    欢迎大家来到我们的项目实战课,本期内容是<基于Pytorch的InceptionNet花卉图像分类实战>.所谓项目课,就是以简单的原理回顾+详细的项目实战的模式,针对具体的某一个主题,进行 ...

  10. 【项目实战课】基于Pytorch的Semantic_Human_Matting(人像软分割)实战

    欢迎大家来到我们的项目实战课,本期内容是<基于Pytorch的Semantic_Human_Matting(人像软分割)实战>.所谓项目实战课,就是以简单的原理回顾+详细的项目实战的模式, ...

最新文章

  1. 软件质量与测试 第4周小组作业
  2. Linux预备知识(三):系统调用-用户态/内核态
  3. 对话美摄科技侯康:提升技术,拓展场景 美摄智能汽车视频处理方案已就位
  4. java hive demo_java 操作hive通过jdbc
  5. linux的基础知识——CS模型流程图
  6. phoshop cs6软件提示试用版已过期,怎么办
  7. 【开发工具】之MinGW下makefile的编写
  8. mysql 分区 key 写法_mysql数据库KEY分区用法
  9. 基于序列图像的三维体绘的视线投射算法
  10. 嵌入式C语言编码规范
  11. oracle得oem,Oracle--OEM与常见故障处理
  12. word域转换html,word域代码转换html丢失解决办法.docx
  13. donet 微服务开发 学习-熔断降级 Polly
  14. 如何使用Hyper-V Manager和Powershell合并Hyper-V检查点
  15. html + js实现马赛克画板
  16. Java实习生常规技术面试题每日十题Java基础(三)
  17. 【年度盘点】2016年互联网10大热点,谁在沸腾谁在死去?
  18. python控制画笔尺寸_Python turtle库的画笔控制说明
  19. iOS开发:兼容适配iPhone X
  20. [乐意黎原创]OFO小黄车提示你有未完成订单/未知错误的解决方法

热门文章

  1. HC-SR04 超声波原理图讲解与时序分析与arduino使用
  2. 传感器:HC-SR04超声波传感器原理(底部附代码)
  3. 总结Windows查看产品密匙方法
  4. 文本数据挖掘之文本信息抽取
  5. 平面设计和网页设计的区别是什么
  6. Total Commander的SFTP插件安装
  7. linux看门狗定时器例子,看门狗定时器特殊功能寄存器及实例软件设计
  8. 网易视频云:为何说张三丰是个优秀的程序员?
  9. 文化网,武汉文化网,湖北文化网——炎黄文化常识
  10. redis-狂神基础版