專案實戰:Qt+OpenCV大家來找茬(Qt抓圖,穿透應用,識別區別,框選區別,微調位置)

21497936發表於2022-05-16

前言

  本專案的出現理由只是筆者的一個念頭,於是利用專業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技術點

OpenCV技術點

專案模組化部署

  專案的環境為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 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程式碼: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_OBJECTpublic:
    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::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
;
}


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/70010283/viewspace-2894375/,如需轉載,請註明出處,否則將追究法律責任。

相關文章