前言
本项目的出现理由只是笔者的一个念头,于是利用专业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);
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();
}
该类的主要作用:
- 作为主窗口提供一个套入找茬游戏界面的区域;
- 提供可以动态选取抓取区域的控件;
- 提供微调控件,微调应用窗口,并且让DrawWidget窗口与透明区域位置同步改变;
- 提供识别触发按钮,将识别结果反馈到DrawWidget;
- 清空按钮,将识别的结果进行清空,也就是删除识别结果的矩形;
#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_OBJECT
public:
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
#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 1
QRegion r1(_rectApplication);
QRegion r2(_rectGame);
QRegion r3 = r1 - r2;
setMask(r3);
#endif
QWidget::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头文件和库文件
- 提供接口输入2个同样大小的矩形、阈值和能识别的最小矩形。
- 核心算法:先灰度图->阈值化->寻找边界->识别最小矩形
(最开始算法进行了滤波,闭运算,因为实际有可能存在两幅图截屏就有色差导致灰度图色差小,实际有可能原图色差较小导致灰度色差较小,实际有可能不同的点较少导致滤波去掉了这些点,以上三种经过测试都是存在的)。
#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
#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::Mat
cv::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;
}
}
}
#endif
cv::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);
#else
mdianMat = threshMat.clone();
#endif
cv::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);
#else
closeMat = 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;
}
#endif
listRect.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;
}