PDA

View Full Version : OpenCV causes access violation only during timerEvent



derekkingston
21st January 2010, 03:30
I've been trying to integrate Qt and OpenCV and ran into a strange problem: some OpenCV functions cause access violations, but only when called during a timerEvent. I simplified the code as much as possible as a proof of concept (see below). The two functions that crash are cvCvtColor (when converting from BGR to Gray) and cvCanny when the sobel aperture has a size greater than 3. Both of these functions work when called anywhere else in the program (e.g. constructor or main). But when called from a timerEvent, an access violation crashes the program. Any ideas?

WinXP
Qt 4.6.1 (mingw)
OpenCV 2.0.0a

CvDebug.pro


TARGET = QtOpenCV
TEMPLATE = app

INCLUDEPATH += C:\OpenCV\include\opencv
LIBS += -L"C:\OpenCV\lib" -lcv200 -lhighgui200 -lcxcore200
SOURCES += main.cpp CvDebug.cpp
HEADERS += CvDebug.h


main.cpp


#include <QtGui/QApplication>
#include "CvDebug.h"

int main(int argc, char **argv)
{
QApplication a(argc, argv);
CvDebug w;
w.show();
return a.exec();
}


CvDebug.h


#ifndef CVDEBUG_H
#define CVDEBUG_H

#include <QtGui/QMainWindow>
#include <cv.h>
#include <highgui.h>

class CvDebug : public QMainWindow
{
Q_OBJECT

public:
CvDebug(QWidget *parent = 0);
~CvDebug();
CvCapture *camera;

protected:
void timerEvent(QTimerEvent*);
};

#endif // CVDEBUG_H


CvDebug.cpp


#include "CvDebug.h"
#include <cv.h>
#include <highgui.h>
#include <cxcore.h>

CvDebug::CvDebug(QWidget *parent) : QMainWindow(parent)
{
cvNamedWindow( "Color", CV_WINDOW_AUTOSIZE );
cvNamedWindow( "Gray", CV_WINDOW_AUTOSIZE );
camera = cvCreateCameraCapture(0);

startTimer(100); // msec
}

CvDebug::~CvDebug()
{
cvDestroyWindow( "Color" );
cvDestroyWindow( "Gray" );
cvReleaseCapture(&camera);
}

void CvDebug::timerEvent(QTimerEvent*)
{
IplImage* image = cvQueryFrame( camera );
cvShowImage( "Color", image);
IplImage* grayImage = cvCreateImage( cvGetSize(image), IPL_DEPTH_8U, 1);
cvCvtColor( image, grayImage, CV_BGR2GRAY );
cvShowImage( "Gray", grayImage );
}

spud
21st January 2010, 15:03
You're going to have to choose if you want to use the Qt Gui system or the one provided in highgui(cvNamedWindow cvShowImage). Both run a message pump and can't be used simultaneously. If you want to stick to Qt, you should convert the IplImage to a QImage and display it on a QLabel or a QGraphicsView or similar.

If you search the forum, you will find many posts on this exact topic.

derekkingston
21st January 2010, 18:04
Thanks for the reply spud.

I actually started this project by searching these forums and used ideas from here (http://www.qtcentre.org/threads/11655-OpenCV-integration?highlight=opencv). I have a working project where opencv does quite a number of image processing functions and displays them using a pixmap on a label. I noticed the access violation when I started adjusting parameters in cvCanny (note that with default parameters cvCanny does *not* crash). The example code in the above post was simply to get the code to a minimal size so others could run and see the same error. If you comment out line 27 of CvDebug.cpp, then that code runs fine. Put line 27 back in (cvCvtColor) and it crashes.

As far as I understand, the only event manager in opencv is the highgui function cvWaitKey (http://opencv.willowgarage.com/documentation/highgui.html) - there is no other way to start/receive events. That being said, I'll try to strip all highgui functions from my program and see if I can still crash it with a call to cvCvtColor in the timerEvent.

derekkingston
21st January 2010, 23:40
I modified the proof-of-concept code to remove any of OpenCV's highgui functions. Even after the change, I am experiencing crashes when cvCvtColor is called in the timerEvent. I also tried eliminating the timer event and using a single shot timer, but I am having the same results: without a call to cvCvtColor, the program operates correctly, as soon as cvCvtColor is called when triggered by a timer, an access violation occurs. Really baffled by all of this.

Here is the simple code w/o any highgui functions:

CvDebug.pro


INCLUDEPATH += C:\OpenCV\include\opencv
LIBS += -L"C:\OpenCV\lib" -lcv200 -lcxcore200


main.cpp


#include <QtGui/QApplication>
#include <qtimer.h>
#include "CvDebug.h"

int main(int argc, char **argv)
{
QApplication a(argc, argv);
CvDebug w;
QTimer::singleShot( 1000, &w, SLOT(ConvertColor()) );
w.show();
return a.exec();
}


CvDebug.h


#ifndef CVDEBUG_H
#define CVDEBUG_H

#include <QtGui/QMainWindow>
#include <QImage>
#include <cv.h>

class CvDebug : public QMainWindow
{
Q_OBJECT

public:
CvDebug(QWidget *parent = 0);
~CvDebug();
QImage* qimage;

IplImage* ConvertToIplImage();

public slots:
void ConvertColor();
};

#endif // CVDEBUG_H


CvDebug.cpp


#include "CvDebug.h"
#include <cv.h>
#include <cxcore.h>

CvDebug::CvDebug(QWidget *parent) : QMainWindow(parent)
{
qimage = new QImage("test_pic.jpg");
}

CvDebug::~CvDebug()
{
delete qimage;
}

void CvDebug::ConvertColor()
{
IplImage* image = ConvertToIplImage();
IplImage* grayImage = cvCreateImage( cvGetSize(image), IPL_DEPTH_8U, 1);
cvCvtColor( image, grayImage, CV_BGR2GRAY );

cvReleaseImage( &image );
cvReleaseImage( &grayImage );
}

IplImage* CvDebug::ConvertToIplImage()
{
IplImage* image = cvCreateImage( cvSize(qimage->width(), qimage->height()), IPL_DEPTH_8U, 3 );

int cvIndex = 0, cvLineStart = 0;
for(int y=0; y<qimage->height(); y++)
{
cvIndex = cvLineStart;
for(int x=0; x<qimage->width(); x++)
{
image->imageData[cvIndex+0] = qBlue(qimage->pixel(x,y));
image->imageData[cvIndex+1] = qGreen(qimage->pixel(x,y));
image->imageData[cvIndex+2] = qRed(qimage->pixel(x,y));
cvIndex += 3;
}
cvLineStart += image->widthStep;
}
return image;
}

derekkingston
23rd January 2010, 05:34
Changed compilers to Visual Studio and the program is running fine - I cannot duplicate the crashing behavior. Guess I'll stick with Visual Studio for now then.

Asfer
19th February 2010, 08:56
Hi, I'm having a similar problem.

Using: Qt4.6 OpenCV2.0 MinGW

If I call OpenCV functions (e.g. cvThreshold) inside Qt slots, the application crashes.

If I call the same functions anywhere else (main or constructors), it works.
If I call the functions using QtConcurrent::run() inside the slot, it works.
If I use OpenCV1.0, it works.

Any ideas about what may be causing this conflict? (...other than having to switch compilers )

Cheers