From 1616915ff77fd6207dc6f3af2bd0a89654a18669 Mon Sep 17 00:00:00 2001 From: 020535 <020535@07accd87-1e0b-0410-939d-c05d8a058e03> Date: Thu, 11 Jun 2009 21:51:43 +0000 Subject: [PATCH] Cleared out a load of uneeded stuff. No longer using a "canvas" element or a layout. Now, this is a clean widget. Removed the button. No real reason to keep it as a part of the widget. The paintEvent now correctly draws directly on the widget. Changed Ilp2QImage, no longer makes a clone of the IplImage. Changes to painting, the conversion mechanism, and clearing out unneded stuff removed a bad memory-leak, leaking somewhere around 5.10MBytes/second previously, now leaks one frame when "dying unclean".. git-svn-id: https://dilbert.hig.no/svn/student/020535/qopencamwidget/trunk@171 07accd87-1e0b-0410-939d-c05d8a058e03 --- qopencamwidget.cpp | 123 +++++++++++---------------------------------- qopencamwidget.h | 8 +-- 2 files changed, 29 insertions(+), 102 deletions(-) diff --git a/qopencamwidget.cpp b/qopencamwidget.cpp index cd5d1b2..e5358f5 100644 --- a/qopencamwidget.cpp +++ b/qopencamwidget.cpp @@ -1,7 +1,6 @@ /* - This file is one part of two, that together make - QOpenCamWidget, a Qt 4 widget that displays video input - from a webcam, along with an optional snapshot button. + This file is one part of two, that together make QOpenCamWidget, + a Qt 4 widget that displays video input from a webcam. Copyright (C) 2009 Jon Langseth @@ -48,10 +47,14 @@ * \code * QOpenCamWidget *cw = new QOpenCamWidget(this); * if ( cw->grabCapture(-1) ) { - * cw->setSnapshotVisible(true); * cw->startCapture(); * } * connect( cw, SIGNAL(imageReady(QImage)), this, SLOT(saveImage(QImage))); + * + * QPushButton *trigger = new QPushButton(this); + * trigger->setText("Take picture"); + * connect( trigger, SIGNAL(clicked()), cw, SLOT(startSnap())); + * * \endcode * * \param *parent The parent widget containing this widget, defaults to NULL. @@ -60,72 +63,21 @@ QOpenCamWidget::QOpenCamWidget(QWidget *parent) : QWidget(parent) { - // private CvCapture *nextFrame from class definition + // Setting sane default values (i.e. NULL) for + // private CvCapture *nextFrame and + // private QTimer *frametimer from class definition nextFrame = NULL; - // private QTimer *frametimer from class definition frametimer = NULL; - // private QVBoxLayout *layout from class definition - layout = new QVBoxLayout(this); - - // private QLabel *canvas from class definition - canvas = new QLabel(this); - canvas->setMinimumSize(200, 100); - canvas->setAlignment(Qt::AlignCenter); - - // private QPushButton *trigger from class definition - trigger = new QPushButton(this); - trigger->setText("Take picture"); - trigger->setEnabled(false); - trigger->hide(); - - // private bool trigger_active from class definition - trigger_active = false; - - layout->addWidget(canvas); - this->setLayout(layout); } QOpenCamWidget::~QOpenCamWidget(void) { cvReleaseCapture( &capture ); - delete canvas; - delete trigger; } // ------------------------------------------------------------- // // Public methods (not signals/slots) // ------------------------------------------------------------- // -/*! - * \brief Changes the visibility of the optional built-in "Take snapshot" button. - * - * The widget contains a push-button that optionally can be displayed. When - * visible, this button is located at the bottom of the widget, and causes - * the SLOT QOpenCamWidget::startSnap to be triggered when clicked. - * - * \param visible True makes the button display, and trigger, - * false turns the feature off. False, i.e. no button, is default. - * - **/ -void -QOpenCamWidget::setSnapshotVisible(bool visible) -{ - // Checking both parameter and private "sanity" variable, - // as a sanity- and error-control - if ( visible && !trigger_active ) - { - connect( trigger, SIGNAL(clicked()), this, SLOT(startSnap())); - layout->addWidget(trigger); - trigger->show(); - trigger_active = true; - } - if ( !visible && trigger_active ) - { - layout->removeWidget(trigger); - disconnect( trigger, SIGNAL(clicked()), 0, 0 ); - trigger->hide(); - trigger_active = false; - } -} /*! * \brief A paint event is a request to repaint all or part of a widget. * @@ -148,22 +100,18 @@ QOpenCamWidget::paintEvent ( QPaintEvent * event ) if ( nextFrame ) { - // Using this objects painter to draw the image - // causes a cute, but not desired effect.. - //paint->drawImage(event->rect(), *nextFrame); - - // Until I find a better solution on how to do the - // redraw of the image, setPixmap on the canvas - // does do the job. This may cause a performance - // penalty though, and is considered a FIXME - // Another drawback is that the widget does not resize.. - canvas->setPixmap( QPixmap::fromImage(*nextFrame) ); + // To make the widget as blazingly fast as possible + // we output the last captured frame direclty onto + // the widget area. + paint->drawImage(event->rect(), *nextFrame); } else { - canvas->setText("No data, check/test camera"); + paint->drawText(event->rect(),"No data, check/test camera"); } paint->end(); + // Clean up.. + delete(paint); } @@ -192,9 +140,8 @@ QOpenCamWidget::grabCapture(int source) IplImage *image = cvRetrieveFrame(capture); QSize t_size = QSize(image->width,image->height); - qDebug() << "Device image format: " << image->width << "x" << image->height; - canvas->setMinimumSize(t_size); - canvas->setMaximumSize(t_size); + this->setMinimumSize(t_size); + this->setMaximumSize(t_size); return true; } @@ -217,9 +164,8 @@ void QOpenCamWidget::startCapture(void) { frametimer = new QTimer(this); - frametimer->start(70); + frametimer->start(50); connect(frametimer,SIGNAL(timeout()), this,SLOT(grabFrame())); - trigger->setEnabled(true); } /*! @@ -238,15 +184,13 @@ QOpenCamWidget::startCapture(void) * **/ QImage* -QOpenCamWidget::Ipl2QImage(const IplImage *img) +QOpenCamWidget::Ipl2QImage(IplImage *img) { - IplImage *tmp=cvCloneImage(img); - cvConvertImage(img,tmp, CV_CVTIMG_SWAP_RB ); - QImage * qimage = new QImage(reinterpret_cast(tmp->imageData), - tmp->width, - tmp->height, - 3* tmp->width, - QImage::Format_RGB888); + cvConvertImage(img,img, CV_CVTIMG_SWAP_RB); + QImage * qimage = new QImage( + reinterpret_cast(img->imageData), + img->width, img->height, + 3* img->width, QImage::Format_RGB888); return qimage; } @@ -265,16 +209,11 @@ QOpenCamWidget::Ipl2QImage(const IplImage *img) **/ void QOpenCamWidget::grabFrame(void) { - if ( !capture ) - { - qDebug() << "Capture device not ready!"; - return; - } + if ( !capture ) { qDebug() << "Capture device not ready!"; return; } cvGrabFrame(capture); IplImage *iplimage = cvRetrieveFrame(capture); - if (iplimage) { nextFrame = Ipl2QImage(iplimage); @@ -283,6 +222,7 @@ void QOpenCamWidget::grabFrame(void) { nextFrame = NULL; } + update(); } @@ -293,11 +233,6 @@ void QOpenCamWidget::grabFrame(void) * stopped, and the last displayed frame is "captured", and made * available through the emitting of the class imageReady SIGNAL. * - * With the "Take snapshot" button visible (setSnapshotVisible(true)), - * this SLOT is triggered when the user clicks on the trigger button. - * If you do not wish to use the internal trigger button, you - * will have to add a different mechanism to trigger this SLOT. - * * It is possible, though I would not recommend, to use repeated * triggering of this slot to do repeated frame-capture, and thus * make a form of "Animation" or "Video" capture. @@ -309,8 +244,6 @@ void QOpenCamWidget::startSnap(void) if (frametimer->isActive()) { frametimer->stop(); - qDebug() << "SNAP!"; - emit imageReady(QImage(*nextFrame)); frametimer->start(); } diff --git a/qopencamwidget.h b/qopencamwidget.h index ef93a15..560d78b 100644 --- a/qopencamwidget.h +++ b/qopencamwidget.h @@ -35,11 +35,6 @@ class QOpenCamWidget CvCapture *capture; QTimer *frametimer; QImage *nextFrame; - //QImage *snapshot; - QLabel *canvas; - QVBoxLayout *layout; - QPushButton *trigger; - bool trigger_active; public: // Defaults, standard elements ;) @@ -50,10 +45,9 @@ class QOpenCamWidget void paintEvent ( QPaintEvent * event ); // Public methods specific to this class - void setSnapshotVisible( bool visible ); bool grabCapture(int source); void startCapture(void); - QImage* Ipl2QImage(const IplImage *img); + QImage* Ipl2QImage(IplImage *img); public slots: void grabFrame(void); -- 2.39.2