简体   繁体   English

如何在Qt GUI应用程序中循环并显示qimage

[英]how to work the loop in Qt GUI application and display the qimage

I am new to Qt and OpenCV and need help with the following problem. 我是Qt和OpenCV的新手,并且需要以下问题的帮助。

I am developing a code to count vehicles coming to a park. 我正在开发一个代码来计算来公园的车辆。 Pre-obtained input video is used to develop the algorithm. 预先获得的输入视频用于开发算法。 I have chosen a Qt widget application with OpenCV for this. 为此,我选择了带有OpenCV的Qt小部件应用程序。 Currently when compiling, the loop below is skipped. 当前在编译时,下面的循环被跳过。

for( ; contour != 0; contour = contour->h_next ) 

                {
                    bndRect = cvBoundingRect(contour, 0);

                    ui->txtXYnew->appendPlainText("one contour");
                    pt1.x = bndRect.x;
                    pt1.y = bndRect.y;
                    pt2.x = bndRect.x + bndRect.width;
                    pt2.y = bndRect.y + bndRect.height;

                    printf("--------------------\n");
                 cvRectangle(newImage, pt1, pt2, CV_RGB(255,0,0), 1); 
                 }

and the compilation moves to the next section. 编译将移至下一部分。 Why is that, am I using the timer function wrong ? 为什么会这样,我使用计时器功能错了吗? (I have tested this in a console application and it worked fine both Qt and Visual Studio). (我已经在控制台应用程序中对此进行了测试,并且Qt和Visual Studio都可以正常工作)。

I have used two labels, one to display the input frame, and the second for the processed frame. 我使用了两个标签,一个用于显示输入帧,第二个用于已处理的帧。 Currently in the processed frame a black frame is shown. 当前在已处理的帧中显示黑框。 but it should show the processed frame with rectangles drawn around contours. 但它应显示经过处理的框架,并在轮廓周围绘制矩形。

Is there any way to correct this code ? 有什么办法可以纠正此代码? Below is the complete code. 以下是完整的代码。

#include "dialog.h"
#include "ui_dialog.h"
#include  <QtCore>
#include  <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv/cv.h>
using namespace cv;

using namespace std;

Dialog::Dialog(QWidget *parent) :QDialog(parent), ui(new Ui::Dialog)
{
ui->setupUi(this);

inputMovie = cvCaptureFromAVI("E:\\pk.avi");
if (!inputMovie){
   ui->txtXYnew->appendPlainText("error video");
   return;
}


tmrTimer=new QTimer(this);
connect(tmrTimer,SIGNAL(timeout()),this,SLOT(processedframesandudateGUI()));
tmrTimer->start(25);


}
//////////////////////////////////////////////////////////////////////////////////
Dialog::~Dialog()
{
delete ui;
}

/////////////////////////////////////////////////////////////////////////////////
void Dialog::processedframesandudateGUI(){

    CvRect bndRect = cvRect(0,0,0,0);

    CvPoint pt1, pt2;


    CvSize imgSize;
    imgSize.width = 540;
    imgSize.height = 432;
greyImage = cvCreateImage( imgSize, IPL_DEPTH_8U, 1);
movingAverage = cvCreateImage( imgSize, IPL_DEPTH_32F, 3);
colourImage = cvQueryFrame(inputMovie);


bool first = true;


        if(!colourImage)
           { ui->txtXYnew->appendPlainText("no frames");
            return;}

        if(first)
                {
                        difference = cvCloneImage(colourImage);
                        temp = cvCloneImage(colourImage);
                        cvConvertScale(colourImage, movingAverage, 1.0, 0.0);

                    first = false;
                }

        cvConvertScale(movingAverage, temp, 1.0, 0.0);
        cvAbsDiff(colourImage,temp,difference);


        cvCvtColor(difference, greyImage, CV_RGB2GRAY);

        cvThreshold(greyImage,greyImage, 70, 255, CV_THRESH_BINARY);


        newImage = cvCloneImage(colourImage);

        cvDilate(greyImage, greyImage, 0, 18);
        cvErode(greyImage, greyImage, 0, 10);

       CvMemStorage* storage = cvCreateMemStorage(0);
       CvSeq* contour = 0;

         ui->txtXYnew->appendPlainText("contour");
         printf("******\n");

  cvFindContours( greyImage, storage, &contour, sizeof(CvContour), CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE);


              for( ; contour != 0; contour = contour->h_next )

                {
                    bndRect = cvBoundingRect(contour, 0);

                    ui->txtXYnew->appendPlainText("one contour");
                    pt1.x = bndRect.x;
                    pt1.y = bndRect.y;
                    pt2.x = bndRect.x + bndRect.width;
                    pt2.y = bndRect.y + bndRect.height;

                    printf("--------------------\n");
                 cvRectangle(newImage, pt1, pt2, CV_RGB(255,0,0), 1);


                }

     printf("here\n");

    cvCvtColor(colourImage, colourImage, CV_BGR2RGB);
    QImage qimgOriginal((uchar*)colourImage->imageData,colourImage->width, colourImage->height, colourImage->widthStep, QImage::Format_RGB888);
    QImage qimgProcessed((uchar*)newImage->imageData,newImage->width, newImage->height, newImage->widthStep, QImage::Format_RGB888);

    ui->label->setPixmap(QPixmap::fromImage(qimgOriginal));
    ui->label->resize(ui->label->pixmap()->size());
    ui->txtXYnew->appendPlainText("one frame");

    ui->label_2->setPixmap(QPixmap::fromImage(qimgProcessed));
    ui->label_2->resize(ui->label_2->pixmap()->size());

    cvReleaseImage(&temp);
    cvReleaseImage(&difference);
    cvReleaseImage(&greyImage);
    cvReleaseImage(&movingAverage);


}


///////////////////////////////////////////////////////////////////////////////////////
void Dialog::on_pushButton_clicked()
{

if(tmrTimer->isActive()==true)
{
    tmrTimer->stop();
    ui->pushButton->setText("resume");
}
else
{
    tmrTimer->start(25);
    ui->pushButton->setText("pause");
}
}


Below is shown the dialog.h (header file) code. 下面显示了dialog.h(头文件)代码。

#ifndef DIALOG_H
#define DIALOG_H
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
using namespace std;
using namespace cv;

//////////////////////////////////////////////////////////////
#include <QDialog>

namespace Ui {
class Dialog;
}
/////////////////////////////////////////////////////////////////////////
class Dialog : public QDialog
{
Q_OBJECT


public:
explicit Dialog(QWidget *parent = 0);
~Dialog();


public slots:
void processedframesandudateGUI();

private slots:

void on_pushButton_clicked();

private:
Ui::Dialog *ui;

QImage qimgOriginal;
QImage qimgProcessed;

IplImage* greyImage ;
IplImage* colourImage;
IplImage* newImage;
IplImage* movingAverage ;
IplImage* difference;
IplImage* temp;
CvCapture* inputMovie;
QTimer *tmrTimer;



};

#endif // DIALOG_H

edit: 编辑:

i still ddn't found any luck. 我仍然找不到运气。 i fallowed the method described by Chernobyl and it also skipped the loop. 我不喜欢切尔诺贝利描述的方法,它也跳过了循环。 can anybody solve this. 谁能解决这个问题。 i am using Qt 5.3.1 for Windows 32-bit with MinGW and this code compiles perfectly on console application.any support guys. 我正在Windows 32位的MinGW上使用Qt 5.3.1,并且此代码可在控制台application.any支持人员上完美编译。 still waiting for a answer. 还在等待答案。

In your code you intializes 'contour' with 在您的代码中,您使用初始化了“轮廓”

{ CvSeq* contour = 0; {CvSeq *等高线= 0; } }

to zero. 归零。 This is followed by the loop with the condition 'contour != 0;' 随后是条件为“轮廓!= 0;”的循环。

{ for( ; contour != 0; contour = contour->h_next ) } {for(;轮廓!= 0;轮廓=轮廓-> h_next)}

This, the compiler recognizes that the condition to excecute the loop body will never fullfilled and skips the loop body. 这样,编译器意识到执行循环体的条件将永远不会满足,并跳过循环体。

I think that all other code is normal and works good, so I show my loop, I try adapt my code to your but I don't so sure. 我认为所有其他代码都是正常的并且可以正常工作,因此我展示了我的循环,我尝试将代码修改为适合您的代码,但我不太确定。

//this is our containers
        std::vector<std::vector<cv::Point> > contours; // Vector for storing contour
        std::vector<cv::Vec4i> hierarchy;
        cv::Rect rect;

//now we try to find contours on the grayscale image
        findContours( greyImage, contours, hierarchy,CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE );

        for( int i = 0; i< contours.size(); i++ ) // iterate through each contour.
         {
          double a = contourArea( contours[i],false);  //  Find the area of contour

          if(a > 30)//you can delete this lines if you don't want search big contours
          {
          rect = boundingRect(contours[i]); // Find the bounding rectangle 
          cv::Point2f centerCircle;
          float rad;
          cv::minEnclosingCircle(contours[i],centerCircle,rad);//search circle
          cv::rectangle(newImage, rect,  cv::Scalar(255,0,0),1, 8,0);//draw rect
          cv::circle(newImage, centerCircle,rad,  cv::Scalar(255,0,0),1, 8,0);//draw circle

         }
         }

Set picture but this is not so useful 设置图片,但这不是很有用

cv::cvtColor(frame,frame,CV_BGR2RGB);
cv::resize(frame,frame,cv::Size2i(ui->label->geometry().width(),ui->label->geometry().height()));
QImage image1((uchar*)frame.data,frame.cols,frame.rows,frame.step,QImage::Format_RGB888);
QPixmap px1(QPixmap::fromImage(image1));
ui->label_2->setPixmap(px1);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM