我是Qt和OpenCV的新手,需要帮助解决以下问题。
我正在开发一个代码来计算来到公园的车辆。预先获得的输入视频用于开发算法。我为此选择了一个带OpenCV的Qt小部件应用程序。目前在编译时,会跳过下面的循环。
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);
}
,编译转到下一部分。为什么呢,我使用定时器功能错了吗? (我在控制台应用程序中对此进行了测试,它在Qt和Visual Studio中都运行良好)。
我使用了两个标签,一个用于显示输入帧,另一个用于处理帧。目前在处理的帧中示出了黑色帧。但是它应该显示处理过的框架,并在轮廓周围绘制矩形。
有没有办法纠正这段代码?以下是完整的代码。
#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");
}
}
下面显示了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
编辑:
我仍然没有找到任何运气。我休闲切尔诺贝利描述的方法,它也跳过了循环。任何人都可以解决这个问题我正在使用Qt 5.3.1 for Windows 32-bit with MinGW,这段代码在控制台应用程序上完美编译。支持人员。还在等待答案。
答案 0 :(得分:0)
在您的代码中,您使用
初始化“轮廓”{CvSeq * contour = 0; }
为零。接下来是条件'contour!= 0;'的循环。
{for(; contour!= 0; contour = contour-&gt; h_next)}
这样,编译器会认识到执行循环体的条件永远不会填满并跳过循环体。
答案 1 :(得分:0)
我认为所有其他代码都是正常的并且运行良好,所以我展示了我的循环,我尝试调整我的代码但我不太确定。
//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
}
}
设置图片,但这不太有用
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);