1 down vote favorite
Recently, I have done a graphical user interface in C++/Qt/OpenCV on Debian 6.0. It achieves image processing (Canny Edge) on a webcam video streaming.
At the execution, the video is corrupted. The most annoying is this bug is not reproducible, it appears randomly.
Here's an example of corrupted video :
This problem seems not to come from the webcam because a simple OpenCV display code shows a good video.
Into my Qt code, I use a main class inherited from QMainWindow. The "start_webcam" button is linked to the "start_webcam" slot by :
startwebcamAct
= new QAction(tr
("&Start Webcam"),
this);
connect(startwebcamAct, SIGNAL(triggered()), this, SLOT(start_webcam()));
startwebcamAct = new QAction(tr("&Start Webcam"), this);
connect(startwebcamAct, SIGNAL(triggered()), this, SLOT(start_webcam()));
To copy to clipboard, switch view to plain text mode
Then, the "start_webcam" function uses a QTimer as follows :
void ImageViewer::start_webcam()
{
webcam_on = 1;
invertWebcam = 0;
close_current();
updateStatusWebcam(webcam_on);
// Init capture
capture = cvCaptureFromCAM(0);
first_image = cvQueryFrame(capture);
// Init current qimage
current_qimage
= QImage(QSize(first_image
->width,first_image
->height
),
QImage::Format_RGB32);
resize(first_image->width,first_image->height);
// start QTimer
connect(timer,SIGNAL(timeout()),this,SLOT(query_frame()));
timer->start(0);
}
void ImageViewer::start_webcam()
{
webcam_on = 1;
invertWebcam = 0;
close_current();
updateStatusWebcam(webcam_on);
// Init capture
capture = cvCaptureFromCAM(0);
first_image = cvQueryFrame(capture);
// Init current qimage
current_qimage = QImage(QSize(first_image->width,first_image->height),QImage::Format_RGB32);
resize(first_image->width,first_image->height);
// start QTimer
timer = new QTimer(this);
connect(timer,SIGNAL(timeout()),this,SLOT(query_frame()));
timer->start(0);
}
To copy to clipboard, switch view to plain text mode
with "query_frame" function (where I use repaint() ) :
void ImageViewer::query_frame()
{
webcam_off = 0;
IplImage* frame = cvQueryFrame(capture);
int w = frame->width;
int h = frame->height;
if (matrixMode)
{
current_image = cvCreateImage(cvGetSize(frame),8,3);
cvCvtColor(frame,current_image,CV_BGR2RGB);
int cvIndex = 0;
int cvLineStart = 0;
unsigned char red,green,blue;
for(int j = 0; j < h; j++)
{
cvIndex = cvLineStart;
for(int i = 0; i < w; i++)
{
red = 0;
green = current_image->imageData[cvIndex+1];
blue = 0;
current_qimage.setPixel(i,j,qRgb(red, green, blue));
cvIndex += 3;
}
cvLineStart += current_image->widthStep;
}
}
gaussianfilter(webcam_off);
border_detect(webcam_off);
if (invertWebcam)
invertvalues(webcam_off);
cvReleaseImage(¤t_image);
repaint();
}
void ImageViewer::query_frame()
{
webcam_off = 0;
IplImage* frame = cvQueryFrame(capture);
int w = frame->width;
int h = frame->height;
if (matrixMode)
{
current_image = cvCreateImage(cvGetSize(frame),8,3);
cvCvtColor(frame,current_image,CV_BGR2RGB);
int cvIndex = 0;
int cvLineStart = 0;
unsigned char red,green,blue;
for(int j = 0; j < h; j++)
{
cvIndex = cvLineStart;
for(int i = 0; i < w; i++)
{
red = 0;
green = current_image->imageData[cvIndex+1];
blue = 0;
current_qimage.setPixel(i,j,qRgb(red, green, blue));
cvIndex += 3;
}
cvLineStart += current_image->widthStep;
}
}
gaussianfilter(webcam_off);
border_detect(webcam_off);
if (invertWebcam)
invertvalues(webcam_off);
cvReleaseImage(¤t_image);
repaint();
}
To copy to clipboard, switch view to plain text mode
The repaint() function calls (immediatly ?) paintEvent :
{
painter.
drawImage(QRect(0,
0,current_qimage.
width(),current_qimage.
height()),current_qimage
);
}
void ImageViewer::paintEvent(QPaintEvent*)
{
QPainter painter(this);
painter.drawImage(QRect(0,0,current_qimage.width(),current_qimage.height()),current_qimage);
}
To copy to clipboard, switch view to plain text mode
At the execution, if I maximize the GUI window, video is shown correctly ; here's an example of this good display :
This lag seems to be a conflict between the QTimer into "start_webcam()" and the "paintEvent" function but I am not sure.
I tried to use update() instead of repaint() but the problem remains.
Anyone could give me a clue on this kind of bug ?
Bookmarks