美文网首页
项目实战:Qt+OpenCV大家来找茬(Qt抓图,穿透应用,识别

项目实战:Qt+OpenCV大家来找茬(Qt抓图,穿透应用,识别

作者: 红模仿_红胖子 | 来源:发表于2022-05-16 09:57 被阅读0次

    前言

      本项目的出现理由只是笔者的一个念头,于是利用专业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

    #ifndefDRAWWIDGET_H#defineDRAWWIDGET_H#include<QWidget>namespaceUi{classDrawWidget;}classDrawWidget:publicQWidget{Q_OBJECTpublic:explicitDrawWidget(QWidget*parent=0);~DrawWidget();public:voidsetRect(intx,inty,intwidth,intheight);voidsetRect2(intx,inty,intwidth,intheight);voidclearListRect();voidsetListRect(QList<QRect>listRect);protected:voidinitControl();protected:voidpaintEvent(QPaintEvent*event);protected:voiddrawSelectRect(QPainter*painter);voiddrawListRect(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")#defineLOGqDebug()<<__FILE__<<__LINE__<<QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss:zzz")DrawWidget::DrawWidget(QWidget*parent):QWidget(parent),ui(newUi::DrawWidget),_colorRect(Qt::red){ui->setupUi(this);setWindowFlag(Qt::FramelessWindowHint);setAttribute(Qt::WA_TranslucentBackground);setAttribute(Qt::WA_TransparentForMouseEvents);initControl();}DrawWidget::~DrawWidget(){deleteui;}voidDrawWidget::setRect(intx,inty,intwidth,intheight){_rect.setRect(x,y,width,height);}voidDrawWidget::setRect2(intx,inty,intwidth,intheight){_rect2.setRect(x,y,width,height);LOG<<_rect<<_rect2;}voidDrawWidget::clearListRect(){_listRect.clear();update();}voidDrawWidget::setListRect(QList<QRect>listRect){_listRect=listRect;update();}voidDrawWidget::initControl(){// 置顶::SetWindowPos(HWND(this->winId()),HWND_TOPMOST,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE|SWP_SHOWWINDOW);}voidDrawWidget::paintEvent(QPaintEvent*event){QPainterpainter(this);drawSelectRect(&painter);drawListRect(&painter);}voidDrawWidget::drawSelectRect(QPainter*painter){painter->save();painter->setPen(QPen(_colorRect,4));painter->drawRect(_rect);painter->drawRect(_rect2);painter->restore();}voidDrawWidget::drawListRect(QPainter*painter){painter->save();painter->setPen(QPen(Qt::white,2));for(intindex=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(intindex=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

    #ifndefFINDDIFFERENCEWIDGET_H#defineFINDDIFFERENCEWIDGET_H#include<QWidget>#include<QPainter>#include<QRect>#include<QRegion>#include<QList>#include"FindDifferenceManager.h"#include"DrawWidget.h"#include<QElapsedTimer>namespaceUi{classFindDifferenceWidget;}classFindDifferenceWidget:publicQWidget{Q_OBJECTpublic:explicitFindDifferenceWidget(QWidget*parent=0);~FindDifferenceWidget();protected:voidinitControl();voidupdateGameRect();protectedslots:voidslot_initControl();protected:voidpaintEvent(QPaintEvent*event);voidresizeEvent(QResizeEvent*event);voidmoveEvent(QMoveEvent*event);voidcloseEvent(QCloseEvent*event);protectedslots:voidslot_valueChanged(intvalue);protectedslots:voidslot_findResult(boolresult,QList<QRect>listRect=QList<QRect>());privateslots:voidon_pushButton_do_clicked();voidon_pushButton_up_clicked();voidon_pushButton_left_clicked();voidon_pushButton_right_clicked();voidon_pushButton_down_clicked();voidon_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")#defineLOGqDebug()<<__FILE__<<__LINE__<<QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss:zzz")FindDifferenceWidget::FindDifferenceWidget(QWidget*parent):QWidget(parent),ui(newUi::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(){deleteui;}voidFindDifferenceWidget::initControl(){// 置顶::SetWindowPos(HWND(this->winId()),HWND_TOPMOST,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE|SWP_SHOWWINDOW);// 识别类_pFindDifferenceManager=newFindDifferenceManager();connect(_pFindDifferenceManager,SIGNAL(signal_findResult(bool,QList<QRect>)),this,SLOT(slot_findResult(bool,QList<QRect>)));// 初始化_captionHeigh=26;_margin=3;updateGameRect();_pDrawWidget=newDrawWidget();_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());}voidFindDifferenceWidget::updateGameRect(){_rectApplication=QRect(-_margin,-_captionHeigh,rect().width()+_margin*2,rect().height()+_captionHeigh+_margin);_rectGame=QRect(_margin,rect().height()-_margin-780,1032,780);}voidFindDifferenceWidget::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());}voidFindDifferenceWidget::paintEvent(QPaintEvent*event){#if1QRegionr1(_rectApplication);QRegionr2(_rectGame);QRegion r3=r1-r2;setMask(r3);#endifQWidget::paintEvent(event);}voidFindDifferenceWidget::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());}}voidFindDifferenceWidget::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();}voidFindDifferenceWidget::closeEvent(QCloseEvent*event){_pDrawWidget->hide();_pDrawWidget->deleteLater();}voidFindDifferenceWidget::slot_valueChanged(intvalue){_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);}elseif(pSpinBox==ui->spinBox_image2Width){ui->spinBox_image1Width->setValue(value);}elseif(pSpinBox==ui->spinBox_image1Height){ui->spinBox_image2Height->setValue(value);}elseif(pSpinBox==ui->spinBox_image2Height){ui->spinBox_image1Height->setValue(value);}}voidFindDifferenceWidget::slot_findResult(boolresult,QList<QRect>listRect){if(result){LOG<<listRect;_pDrawWidget->setListRect(listRect);}}voidFindDifferenceWidget::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);}voidFindDifferenceWidget::on_pushButton_up_clicked(){setGeometry(geometry().x(),geometry().y()-1,geometry().width(),geometry().height());}voidFindDifferenceWidget::on_pushButton_left_clicked(){setGeometry(geometry().x()-1,geometry().y(),geometry().width(),geometry().height());}voidFindDifferenceWidget::on_pushButton_right_clicked(){setGeometry(geometry().x()+1,geometry().y(),geometry().width(),geometry().height());}voidFindDifferenceWidget::on_pushButton_down_clicked(){setGeometry(geometry().x(),geometry().y()+1,geometry().width(),geometry().height());}voidFindDifferenceWidget::on_pushButton_clear_clicked(){_pDrawWidget->setListRect(QList<QRect>());}

    OpenCV代码:FindDifferenceManager

      识别不同处代码类功能:

    引入OpenCV头文件和库文件

    提供接口输入2个同样大小的矩形、阈值和能识别的最小矩形。

    核心算法:先灰度图->阈值化->寻找边界->识别最小矩形

    (最开始算法进行了滤波,闭运算,因为实际有可能存在两幅图截屏就有色差导致灰度图色差小,实际有可能原图色差较小导致灰度色差较小,实际有可能不同的点较少导致滤波去掉了这些点,以上三种经过测试都是存在的)。

    FindDifferenceManager.h

    #ifndefFINDDIFFERENCEMANAGER_H#defineFINDDIFFERENCEMANAGER_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>classFindDifferenceManager:publicQObject{Q_OBJECTpublic:explicitFindDifferenceManager(QObject*parent=0);private:boolgetRunning()const;signals:voidsignal_findResult(boolresult,QList<QRect>listRect=QList<QRect>());publicslots:voidslot_start();voidslot_stop();publicslots:voidslot_findDiffrence(QImage image,QImage image2,intthresh=20,QRect minRect=QRect(0,0,4,4));protected:cv::Matimage2Mat(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")#defineLOGqDebug()<<__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> ");}boolFindDifferenceManager::getRunning()const{return_running;}voidFindDifferenceManager::slot_start(){if(_running){LOG<<"Failed to"<<__FUNCTION__<<", it's already running.";return;}_running=true;}voidFindDifferenceManager::slot_stop(){if(!_running){LOG<<"Failed to"<<__FUNCTION__<<", it's not running.";return;}_running=false;}voidFindDifferenceManager::slot_findDiffrence(QImage image,QImage image2,intthresh,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)){emitsignal_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);#if0// 整个像素降低5个点的误差(色差)for(introw=0;row<diffAbsMatGray.rows;row++){for(intcol=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;#if0//中值滤波cv::medianBlur(threshMat,mdianMat,3);cv::imshow("6",mdianMat);#elsemdianMat=threshMat.clone();#endifcv::Mat closeMat;#if0// 闭运算: 用拟合小裂缝,消除小型黑洞,并且在平滑较大物体的边界的同时不明显改变其面积。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(intindex=0;index<contours.size();index++){cv::approxPolyDP(cv::Mat(contours[index]),contoursPoly[index],5,true);cv::Rect rect=cv::boundingRect(cv::Mat(contoursPoly[index]));#if0// 小于最小矩形则忽略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);emitsignal_findResult(true,listRect);}cv::MatFindDifferenceManager::image2Mat(QImage image){cv::Mat mat;switch(image.format()){caseQImage::Format_ARGB32:caseQImage::Format_RGB32:caseQImage::Format_ARGB32_Premultiplied:mat=cv::Mat(image.height(),image.width(),CV_8UC4,(void*)image.constBits(),image.bytesPerLine());cv::cvtColor(mat,mat,CV_BGRA2BGR);break;caseQImage::Format_RGB888:mat=cv::Mat(image.height(),image.width(),CV_8UC3,(void*)image.constBits(),image.bytesPerLine());cv::cvtColor(mat,mat,CV_BGR2RGB);break;caseQImage::Format_Indexed8:caseQImage::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();}returnmat;}

    相关文章

      网友评论

          本文标题:项目实战:Qt+OpenCV大家来找茬(Qt抓图,穿透应用,识别

          本文链接:https://www.haomeiwen.com/subject/rhiiurtx.html