I have a question about declare global cv::Mat image in Qt project.



  • @#include "mainwindow.h"
    #include "ui_mainwindow.h"
    #include <QTimer>
    #include <stdio.h>
    #include <iostream>
    #include <opencv2\video\video.hpp>
    #include <opencv2\opencv.hpp>
    #include "opencv2/imgproc/imgproc.hpp"
    #include "opencv2/highgui/highgui.hpp"
    #include "opencv2/flann/miniflann.hpp"
    using namespace cv; // all the new API is put into "cv" namespace. Export its content
    using namespace std;
    int k = 1;
    int imagex=360,imagey=640;
    int m1=1,m2,m3,m4,turnleft,turnright = 1;
    cv::Mat image1(720,1280,CV_8UC3,cv::Scalar(255,255,255));

    MainWindow::MainWindow(QWidget *parent) :QMainWindow(parent),ui(new Ui::MainWindow)
    {

    ui->setupUi(this);
    capture.open("E:\\Six Degree of Separation.avi");
    tmrTimer = new QTimer(this);
    connect(tmrTimer,SIGNAL(timeout()),this,SLOT(ProcessFrameAndUpdateGUI()));
    tmrTimer ->start(20);
    

    }

    MainWindow::~MainWindow()
    {
    delete ui;
    }

    void canny(cv::Mat& img, cv::Mat& out)
    {
    if(img.channels()==3)
    cv::cvtColor(img,out,CV_BGR2GRAY);
    cv::Canny(out,out,100,200);
    cv::threshold(out,out,128,255,cv::THRESH_BINARY_INV);
    }
    void colorreduce(cv::Mat& image){
    int nl=image.rows;
    int nc=image.cols;
    for(int j=0;j<nl;j++){
    uchar*data = image.ptr<uchar>(j);
    for(int i=0; i<nc;i++){
    if (data[i]>125)
    data[i]=0;
    else
    data[i]=255;
    }
    }
    }

    void MainWindow::ProcessFrameAndUpdateGUI(){
    k++;
    capture.read(frame);
    canny(frame,frame1);
    colorreduce(frame1);
    std::vectorcv::Mat planes;
    cv::split(frame,planes);
    planes[2]+=frame1;
    cv::merge(planes,frame3);
    cv::cvtColor(frame3,frame3,CV_BGR2RGB);
    cv::line(image1,cv::Point(imagex,imagey),cv::Point(imagex,imagey-k),cv::Scalar(0,255,0),2,4);
    QImage qimage1((uchar*)image1.data,image1.cols,image1.rows,image1.step,QImage::Format_RGB888);
    QImage qframe3((uchar*)frame3.data,frame3.cols,frame3.rows,frame3.step,QImage::Format_RGB888);
    QImage qframe1((uchar*)frame1.data,frame1.cols,frame1.rows,frame1.step,QImage::Format_Indexed8);
    ui->label->setPixmap(QPixmap::fromImage(qframe3));
    ui->label_2->setPixmap(QPixmap::fromImage(qframe1));
    ui->label_3->setPixmap(QPixmap::fromImage(qimage1));

    }
    void MainWindow::on_pushButton_clicked()
    {
    if(tmrTimer->isActive()==true){
    tmrTimer->stop();
    ui->pushButton->setText("resume");
    }else{
    tmrTimer->start(20);
    ui->pushButton->setText("pause");
    }
    }@

    when i declare cv::Mat image like this code. it dont show anything in the "label_3"
    but when i declare like below code it shows a picture in the "label_3". i declare cv::Mat in void MainWindow::ProcessFrameAndUpdateGUI()

    @#include "mainwindow.h"
    #include "ui_mainwindow.h"
    #include <QTimer>
    #include <stdio.h>
    #include <iostream>
    #include <opencv2\video\video.hpp>
    #include <opencv2\opencv.hpp>
    #include "opencv2/imgproc/imgproc.hpp"
    #include "opencv2/highgui/highgui.hpp"
    #include "opencv2/flann/miniflann.hpp"
    using namespace cv; // all the new API is put into "cv" namespace. Export its content
    using namespace std;
    int k = 1;
    int imagex=360,imagey=640;
    int m1=1,m2,m3,m4,turnleft,turnright = 1;

    MainWindow::MainWindow(QWidget *parent) :QMainWindow(parent),ui(new Ui::MainWindow)
    {

    ui->setupUi(this);
    capture.open("E:\\Six Degree of Separation.avi");
    tmrTimer = new QTimer(this);
    connect(tmrTimer,SIGNAL(timeout()),this,SLOT(ProcessFrameAndUpdateGUI()));
    tmrTimer ->start(20);
    

    }

    MainWindow::~MainWindow()
    {
    delete ui;
    }

    void canny(cv::Mat& img, cv::Mat& out)
    {
    if(img.channels()==3)
    cv::cvtColor(img,out,CV_BGR2GRAY);
    cv::Canny(out,out,100,200);
    cv::threshold(out,out,128,255,cv::THRESH_BINARY_INV);
    }
    void colorreduce(cv::Mat& image){
    int nl=image.rows;
    int nc=image.cols;
    for(int j=0;j<nl;j++){
    uchar*data = image.ptr<uchar>(j);
    for(int i=0; i<nc;i++){
    if (data[i]>125)
    data[i]=0;
    else
    data[i]=255;
    }
    }
    }

    void MainWindow::ProcessFrameAndUpdateGUI(){
    cv::Mat image1(720,1280,CV_8UC3,cv::Scalar(255,255,255));
    k++;
    capture.read(frame);
    canny(frame,frame1);
    colorreduce(frame1);
    std::vectorcv::Mat planes;
    cv::split(frame,planes);
    planes[2]+=frame1;
    cv::merge(planes,frame3);
    cv::cvtColor(frame3,frame3,CV_BGR2RGB);
    cv::line(image1,cv::Point(imagex,imagey),cv::Point(imagex,imagey-k),cv::Scalar(0,255,0),2,4);
    QImage qimage1((uchar*)image1.data,image1.cols,image1.rows,image1.step,QImage::Format_RGB888);
    QImage qframe3((uchar*)frame3.data,frame3.cols,frame3.rows,frame3.step,QImage::Format_RGB888);
    QImage qframe1((uchar*)frame1.data,frame1.cols,frame1.rows,frame1.step,QImage::Format_Indexed8);
    ui->label->setPixmap(QPixmap::fromImage(qframe3));
    ui->label_2->setPixmap(QPixmap::fromImage(qframe1));
    ui->label_3->setPixmap(QPixmap::fromImage(qimage1));

    }
    void MainWindow::on_pushButton_clicked()
    {
    if(tmrTimer->isActive()==true){
    tmrTimer->stop();
    ui->pushButton->setText("resume");
    }else{
    tmrTimer->start(20);
    ui->pushButton->setText("pause");
    }
    }
    @


  • Moderators

    Hi, what's your question?

    Also, your example is quite complicated. Please post a simpler example that shows your problem.



  • my question is how to declare global cv::Mat image. As you see in my code. it only works when I declare cv::mat image1 in void MainWindow::ProcessFrameAndUpdateGUI(). but when i want image1 is globlal image that i want to you in other subroutine not only in MainWindow::ProcessFrameAndUpdateGUI(). I declare:

    #include "mainwindow.h"
    #include "ui_mainwindow.h"
    #include <QTimer>
    #include <stdio.h>
    #include <iostream>
    #include <opencv2\video\video.hpp>
    #include <opencv2\opencv.hpp>
    #include "opencv2/imgproc/imgproc.hpp"
    #include "opencv2/highgui/highgui.hpp"
    #include "opencv2/flann/miniflann.hpp"
    using namespace cv; // all the new API is put into "cv" namespace. Export its content
    using namespace std;
    int k = 1;
    int imagex=360,imagey=640;
    int m1=1,m2,m3,m4,turnleft,turnright = 1;
    cv::Mat image1(720,1280,CV_8UC3,cv::Scalar(255,255,255));

    and when i use image1 in MainWindow::ProcessFrameAndUpdateGUI() it does not work.



  • I avoided answering because I don't have much of an answer. My OpenCV reference is out of the office for a while, but we talked about this issue a few weeks ago when we encountered the issue. All I know is that it is not a Qt issue. It is supposedly not recommended to declare global cv::Mat and you should avoid it. Unfortunately, I tried to find out why and couldn't find the source article from where this came from. Sorry for the lack of explanation. The OpenCV forums would be a better place to find out.



  • If possible, avoid to use global Mat directly in the cpp of MainWindow. But if you really need to have the scope of the Mat in all the MainWindow, you can declare the cv::Mat as a private member class of MainWindow.h.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.