+Consctructs a QWidget based widget for displaying video coming from an OpenCV capture source.
+
+Including webcam data in a Qt application can be problematic, at least as long as Phonon does not support webcams, and the Phonon GStreamer backend only supports simple pipelines.
+This class solves the complexity of adding a webcam view, by using the cross-platform available OpenCV library.
+Limitations, i.e. reasons to read this code and reimplement, are: saving or streaming video is not really available (unless you do repeated timer-triggered connections to the startSnap slot), the widget size is identical to the video source dimensions (it resizes the wodget using setMinimuSize to the video dimensions, and does not handle resizing to sizes above this dimension.
+A paint event is a request to repaint all or part of a widget.
+
+It can happen for one of the following reasons:
+
+
repaint() or update() was invoked,
+
the widget was obscured and has now been uncovered, or
+
many other reasons.
+
+QOpenCamWidget uses the paintEvent to draw each frame onto the screen. The paintEvent itself is regularily triggered by explicit update() calls in QOpenCamWidget::grabFrame().
+
+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.
+
Parameters:
+
+
visible
True makes the button display, and trigger, false turns the feature off. False, i.e. no button, is default.
+By grabbing a source, it is meant to open the capture source, and have it ready to start streaming/capturing frames. Returns true on success, false on error. The grabCapture is separated from the constructor and/or frame-grabbing, so that you may do the error-checking you really should do before proceeding.
+
Parameters:
+
+
source
The OpenCV capture source enumeration index to open
+The actual grabbing and displaying of video frames is performed by a QTimer triggering the SLOT QOpenCamWidget::grabFrame(). startCapture() sets up the timer running this captureFrame loop.
+The SLOT QOpenCamWidget::startSnap() is used to get image frames out from the widget for other uses, like saving or processing. This function relies on the timer created and configured by startCapture(), and as such, this function is the only permitted way to start the actual capture/streaming of video from the source.
+
+Converts from the OpenCV IplImage data structure to a QImage.
+
+OpenCV uses a data strcuture calles IplImage, optimized for computer vision image processing tasks. This code was adapted from kcamwidget.cpp, part of the KDE SVN at playground/multimedia/kcam/kcamwidget.cpp
+In regard that the IplImage can be forced into a format that aligns well with a RBG888-format, the conversion becomes one of the shortes, simples IplImage->QImage I've seen.
+Grabs a frame and causes an update() when triggered.
+
+This is the SLOT that actually reads the video source and causes the widget to display live video. Preferably this slot will never be called my any other signal that a timeout() on the frametimer, which is controlled by QOpenCamWidget::startCapture()
+
+Trigger this slot to save a frame from the widget.
+
+When this slot is triggered, the widgets capture loop is temporarily 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.
+
00001 /*
+00002 QOpenCamWidget demo application main code stup (main.c)
+00003 This file is part of a demonstration application, illustrating
+00004 how to use the QOpenCamWidget, a Qt 4 widget that displays
+00005 video input from a webcam, along with a snapshot button.
+00006
+00007 Copyright (C) 2009 Jon Langseth
+00008
+00009 This program is free software; you can redistribute it and/or
+00010 modify it under the terms of the GNU General Public License
+00011 as published by the Free Software Foundation in its version 2
+00012 of the License.
+00013
+00014 This program is distributed in the hope that it will be useful,
+00015 but WITHOUT ANY WARRANTY; without even the implied warranty of
+00016 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+00017 GNU General Public License for more details.
+00018
+00019 You should have received a copy of the GNU General Public License
+00020 along with this program; if not, write to the Free Software
+00021 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+00022 */
+00023
+00024 #include <QtGui/QApplication>
+00025 #include "view.h"
+00026
+00027 // The contents of this file is simply a Qt Main app stub.
+00028intmain (int argc, char*argv[])
+00029 {
+00030 QApplication app(argc, argv);
+00031 app.setApplicationName("QOpenCamWidget testapp");
+00032 View v;
+00033 v.show();
+00034 return app.exec();
+00035 }
+00036
+
+Generated on Thu Jun 11 01:49:57 2009 for QOpenCamWidget by
+
+ 1.5.6
+
+
diff --git a/doc/html/main_8cpp.html b/doc/html/main_8cpp.html
new file mode 100644
index 0000000..180ec03
--- /dev/null
+++ b/doc/html/main_8cpp.html
@@ -0,0 +1,65 @@
+
+
+QOpenCamWidget: main.cpp File Reference
+
+
+
+
+
00001 /*
+00002 This file is one part of two, that together make
+00003 QOpenCamWidget, a Qt 4 widget that displays video input
+00004 from a webcam, along with an optional snapshot button.
+00005
+00006 Copyright (C) 2009 Jon Langseth
+00007
+00008 This program is free software; you can redistribute it and/or
+00009 modify it under the terms of the GNU General Public License
+00010 as published by the Free Software Foundation in its version 2
+00011 of the License.
+00012
+00013 This program is distributed in the hope that it will be useful,
+00014 but WITHOUT ANY WARRANTY; without even the implied warranty of
+00015 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+00016 GNU General Public License for more details.
+00017
+00018 You should have received a copy of the GNU General Public License
+00019 along with this program; if not, write to the Free Software
+00020 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+00021 */
+00022
+00023 #include "qopencamwidget.h"
+00024
+00025 // ------------------------------------------------------------- //
+00026 // Constructor and Destructor
+00027 // ------------------------------------------------------------- //
+00028
+00060QOpenCamWidget::QOpenCamWidget(QWidget *parent)
+00061 : QWidget(parent)
+00062 {
+00063 // private CvCapture *nextFrame from class definition
+00064 nextFrame = NULL;
+00065 // private QTimer *frametimer from class definition
+00066 frametimer = NULL;
+00067 // private QVBoxLayout *layout from class definition
+00068 layout = new QVBoxLayout(this);
+00069
+00070 // private QLabel *canvas from class definition
+00071 canvas = new QLabel(this);
+00072 canvas->setMinimumSize(200, 100);
+00073 canvas->setAlignment(Qt::AlignCenter);
+00074
+00075 // private QPushButton *trigger from class definition
+00076 trigger = new QPushButton(this);
+00077 trigger->setText("Take picture");
+00078 trigger->setEnabled(false);
+00079 trigger->hide();
+00080
+00081 // private bool trigger_active from class definition
+00082 trigger_active = false;
+00083
+00084 layout->addWidget(canvas);
+00085 this->setLayout(layout);
+00086 }
+00087
+00088QOpenCamWidget::~QOpenCamWidget(void)
+00089 {
+00090 cvReleaseCapture( &capture );
+00091 deletecanvas;
+00092 deletetrigger;
+00093 }
+00094 // ------------------------------------------------------------- //
+00095 // Public methods (not signals/slots)
+00096 // ------------------------------------------------------------- //
+00097
+00109 void
+00110QOpenCamWidget::setSnapshotVisible(bool visible)
+00111 {
+00112 // Checking both parameter and private "sanity" variable,
+00113 // as a sanity- and error-control
+00114 if ( visible && !trigger_active )
+00115 {
+00116 connect( trigger, SIGNAL(clicked()), this, SLOT(startSnap()));
+00117 layout->addWidget(trigger);
+00118 trigger->show();
+00119 trigger_active = true;
+00120 }
+00121 if ( !visible && trigger_active )
+00122 {
+00123 layout->removeWidget(trigger);
+00124 disconnect( trigger, SIGNAL(clicked()), 0, 0 );
+00125 trigger->hide();
+00126 trigger_active = false;
+00127 }
+00128 }
+00143 void
+00144QOpenCamWidget::paintEvent ( QPaintEvent * event )
+00145 {
+00146 QPainter * paint = new QPainter;
+00147 paint->begin(this);
+00148
+00149 if ( nextFrame )
+00150 {
+00151 // Using this objects painter to draw the image
+00152 // causes a cute, but not desired effect..
+00153 //paint->drawImage(event->rect(), *nextFrame);
+00154
+00155 // Until I find a better solution on how to do the
+00156 // redraw of the image, setPixmap on the canvas
+00157 // does do the job. This may cause a performance
+00158 // penalty though, and is considered a FIXME
+00159 // Another drawback is that the widget does not resize..
+00160 canvas->setPixmap( QPixmap::fromImage(*nextFrame) );
+00161 }
+00162 else
+00163 {
+00164 canvas->setText("No data, check/test camera");
+00165 }
+00166 paint->end();
+00167 }
+00168
+00169
+00182 bool
+00183QOpenCamWidget::grabCapture(int source)
+00184 {
+00185 capture = cvCaptureFromCAM(0);
+00186 if (!capture)
+00187 {
+00188 qDebug() << "QOpenCamWidget::grabCapture(" << source << ") failed";
+00189 returnfalse;
+00190 }
+00191 cvGrabFrame(capture); // Grab a single frame, do resizing based on it.
+00192 IplImage *image = cvRetrieveFrame(capture);
+00193 QSize t_size = QSize(image->width,image->height);
+00194
+00195 qDebug() << "Device image format: " << image->width << "x" << image->height;
+00196 canvas->setMinimumSize(t_size);
+00197 canvas->setMaximumSize(t_size);
+00198
+00199 returntrue;
+00200 }
+00201
+00216 void
+00217QOpenCamWidget::startCapture(void)
+00218 {
+00219 frametimer = new QTimer(this);
+00220 frametimer->start(70);
+00221 connect(frametimer,SIGNAL(timeout()), this,SLOT(grabFrame()));
+00222 trigger->setEnabled(true);
+00223 }
+00224
+00240 QImage*
+00241QOpenCamWidget::Ipl2QImage(const IplImage *img)
+00242 {
+00243 IplImage *tmp=cvCloneImage(img);
+00244 cvConvertImage(img,tmp, CV_CVTIMG_SWAP_RB );
+00245 QImage * qimage = new QImage(reinterpret_cast<uchar*>(tmp->imageData),
+00246 tmp->width,
+00247 tmp->height,
+00248 3* tmp->width,
+00249 QImage::Format_RGB888);
+00250 return qimage;
+00251
+00252 }
+00253 // ------------------------------------------------------------- //
+00254 // Public SLOTS
+00255 // ------------------------------------------------------------- //
+00256
+00266voidQOpenCamWidget::grabFrame(void)
+00267 {
+00268 if ( !capture )
+00269 {
+00270 qDebug() << "Capture device not ready!";
+00271 return;
+00272 }
+00273
+00274 cvGrabFrame(capture);
+00275
+00276 IplImage *iplimage = cvRetrieveFrame(capture);
+00277
+00278 if (iplimage)
+00279 {
+00280 nextFrame = Ipl2QImage(iplimage);
+00281 }
+00282 else
+00283 {
+00284 nextFrame = NULL;
+00285 }
+00286 update();
+00287 }
+00288
+00306voidQOpenCamWidget::startSnap(void)
+00307 {
+00308 if ( frametimer ) {
+00309 if (frametimer->isActive())
+00310 {
+00311 frametimer->stop();
+00312 qDebug() << "SNAP!";
+00313
+00314 emit imageReady(QImage(*nextFrame));
+00315 frametimer->start();
+00316 }
+00317 }
+00318 }
+00319
+
+Generated on Thu Jun 11 01:49:57 2009 for QOpenCamWidget by
+
+ 1.5.6
+
+
diff --git a/doc/html/qopencamwidget_8cpp.html b/doc/html/qopencamwidget_8cpp.html
new file mode 100644
index 0000000..58696cc
--- /dev/null
+++ b/doc/html/qopencamwidget_8cpp.html
@@ -0,0 +1,29 @@
+
+
+QOpenCamWidget: qopencamwidget.cpp File Reference
+
+
+
+
+
00001 /*
+00002 This file is one part of two, that together make
+00003 QOpenCamWidget, a Qt 4 widget that displays video input
+00004 from a webcam, along with an optional snapshot button.
+00005
+00006 Copyright (C) 2009 Jon Langseth
+00007
+00008 This program is free software; you can redistribute it and/or
+00009 modify it under the terms of the GNU General Public License
+00010 as published by the Free Software Foundation in its version 2
+00011 of the License.
+00012
+00013 This program is distributed in the hope that it will be useful,
+00014 but WITHOUT ANY WARRANTY; without even the implied warranty of
+00015 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+00016 GNU General Public License for more details.
+00017
+00018 You should have received a copy of the GNU General Public License
+00019 along with this program; if not, write to the Free Software
+00020 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+00021 */
+00022
+00023 #ifndef QOPENCVWIDGET_H
+00024 #define QOPENCVWIDGET_H
+00025 #include <QtGui>
+00026 #include <opencv/cv.h>
+00027 #include <opencv/highgui.h>
+00028
+00029class QOpenCamWidget
+00030 : public QWidget
+00031 {
+00032 Q_OBJECT
+00033
+00034 private:
+00035 CvCapture *capture;
+00036 QTimer *frametimer;
+00037 QImage *nextFrame;
+00038 //QImage *snapshot;
+00039 QLabel *canvas;
+00040 QVBoxLayout *layout;
+00041 QPushButton *trigger;
+00042booltrigger_active;
+00043
+00044 public:
+00045 // Defaults, standard elements ;)
+00046 QOpenCamWidget(QWidget *parent = 0);
+00047 ~QOpenCamWidget(void);
+00048
+00049 // Overides, reimplementation of abstract
+00050 voidpaintEvent ( QPaintEvent * event );
+00051
+00052 // Public methods specific to this class
+00053 voidsetSnapshotVisible( bool visible );
+00054 boolgrabCapture(int source);
+00055 voidstartCapture(void);
+00056 QImage* Ipl2QImage(const IplImage *img);
+00057
+00058 public slots:
+00059 voidgrabFrame(void);
+00060 voidstartSnap();
+00061 signals:
+00062 voidimageReady(QImage snapshot);
+00063 };
+00064
+00065 #endif
+00066
+
+Generated on Thu Jun 11 01:49:57 2009 for QOpenCamWidget by
+
+ 1.5.6
+
+
diff --git a/doc/html/qopencamwidget_8h.html b/doc/html/qopencamwidget_8h.html
new file mode 100644
index 0000000..07f0115
--- /dev/null
+++ b/doc/html/qopencamwidget_8h.html
@@ -0,0 +1,34 @@
+
+
+QOpenCamWidget: qopencamwidget.h File Reference
+
+
+
+
+
00001 /*
+00002 QOpenCamWidget demo application main window (view.c)
+00003 This file is part of a demonstration application, illustrating
+00004 how to use the QOpenCamWidget, a Qt 4 widget that displays
+00005 video input from a webcam, along with a snapshot button.
+00006
+00007 Copyright (C) 2009 Jon Langseth
+00008
+00009 This program is free software; you can redistribute it and/or
+00010 modify it under the terms of the GNU General Public License
+00011 as published by the Free Software Foundation in its version 2
+00012 of the License.
+00013
+00014 This program is distributed in the hope that it will be useful,
+00015 but WITHOUT ANY WARRANTY; without even the implied warranty of
+00016 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+00017 GNU General Public License for more details.
+00018
+00019 You should have received a copy of the GNU General Public License
+00020 along with this program; if not, write to the Free Software
+00021 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+00022 */
+00023
+00024 #include "view.h"
+00025 #include "qopencamwidget.h"
+00026
+00027 // The View class is a QMainWindow, used to display our QOpenCamWidget
+00028 // The constructor of the View takes care of setting up the Widget,
+00029 // and handles the result of a user clicking (or activating) the widget's
+00030 // "Take snapshot" button.
+00031
+00032View::View( QWidget *parent)
+00033 : QMainWindow(parent)
+00034 {
+00035
+00036 // Create the widget, setting the Main window (this) as its parent.
+00037 QOpenCamWidget *cw = newQOpenCamWidget(this);
+00038
+00039 // bool QOpenCamWidget::grabCapture(int source) tries to get a
+00040 // video capture handle from OpenCV, using the source number
+00041 // as the device to open. Here I use -1 as the number, meaning
+00042 // "give me any supported and available video devica you can find".
+00043 if ( cw->grabCapture(-1) )
+00044 {
+00045 // grabCapture() returns true on success. This means that
+00046 // we have a capture device available, and can start streaming
+00047 // video from the device to display on the widget.
+00048
+00049 // TODO: Document this feature..
+00050 cw->setSnapshotVisible(true);
+00051
+00052 // Video output does not start until QOpenCamWidget::startCapture()
+00053 // is explicitly called.
+00054 cw->startCapture();
+00055 }
+00056
+00057 // The QOpenCamWidget does not provide a video stream for further
+00058 // processing, but it does provide a snapshot of the stream if
+00059 // the SLOT void QOpenCamWidget::startSnap(void) is triggered.
+00060 // In this demo app, the slot is connected to the widgets
+00061 // internal "Take snapshot" trigger button, but the SLOT is
+00062 // public, and may easily be triggered from "outside".
+00063 //
+00064 // When startSnap() is triggered, it will use a SIGNAL to return
+00065 // its image, if the aquisition was successful. The image
+00066 // will be available through QOpenCamWidget::imageReady(Qimage);
+00067 // In this sample, I hook that signal up to a slot on this QMainWindow,
+00068 // that saves the image, and exits the application.
+00069 connect( cw, SIGNAL(imageReady(QImage)), this, SLOT(saveImage(QImage)));
+00070
+00071 this->setCentralWidget(cw);
+00072 }
+00073
+00074View::~View(void)
+00075 {
+00076 }
+00077
+00078voidView::saveImage(QImage image)
+00079 {
+00080 // This is the SLOT that recieves QOpenCamWidget::imageReady(QImage) SIGNAL.
+00081 // To keep the example as simple as possible, I do as little as possible..
+00082 qDebug() << "Recieved an image of size "
+00083 << image.width() << "x" << image.height();
+00084 image.save("snapshot.png");
+00085
+00086 QApplication::exit();
+00087 }
+
+Generated on Thu Jun 11 01:49:57 2009 for QOpenCamWidget by
+
+ 1.5.6
+
+
diff --git a/doc/html/view_8cpp.html b/doc/html/view_8cpp.html
new file mode 100644
index 0000000..c3958a2
--- /dev/null
+++ b/doc/html/view_8cpp.html
@@ -0,0 +1,30 @@
+
+
+QOpenCamWidget: view.cpp File Reference
+
+
+
+
+
+Generated on Thu Jun 11 01:49:57 2009 for QOpenCamWidget by
+
+ 1.5.6
+
+
diff --git a/doc/man/man3/QOpenCamWidget.3 b/doc/man/man3/QOpenCamWidget.3
new file mode 100644
index 0000000..3758b7e
--- /dev/null
+++ b/doc/man/man3/QOpenCamWidget.3
@@ -0,0 +1,286 @@
+.TH "QOpenCamWidget" 3 "11 Jun 2009" "QOpenCamWidget" \" -*- nroff -*-
+.ad l
+.nh
+.SH NAME
+QOpenCamWidget \-
+.SH SYNOPSIS
+.br
+.PP
+\fC#include \fP
+.PP
+.SS "Public Slots"
+
+.in +1c
+.ti -1c
+.RI "void \fBgrabFrame\fP (void)"
+.br
+.RI "\fIGrabs a frame and causes an update() when triggered. \fP"
+.ti -1c
+.RI "void \fBstartSnap\fP ()"
+.br
+.RI "\fITrigger this slot to save a frame from the widget. \fP"
+.in -1c
+.SS "Signals"
+
+.in +1c
+.ti -1c
+.RI "void \fBimageReady\fP (QImage snapshot)"
+.br
+.in -1c
+.SS "Public Member Functions"
+
+.in +1c
+.ti -1c
+.RI "\fBQOpenCamWidget\fP (QWidget *parent=0)"
+.br
+.RI "\fIConsctructs a QWidget based widget for displaying video coming from an OpenCV capture source. \fP"
+.ti -1c
+.RI "\fB~QOpenCamWidget\fP (void)"
+.br
+.ti -1c
+.RI "void \fBpaintEvent\fP (QPaintEvent *event)"
+.br
+.RI "\fIA paint event is a request to repaint all or part of a widget. \fP"
+.ti -1c
+.RI "void \fBsetSnapshotVisible\fP (bool visible)"
+.br
+.RI "\fIChanges the visibility of the optional built-in 'Take snapshot' button. \fP"
+.ti -1c
+.RI "bool \fBgrabCapture\fP (int source)"
+.br
+.RI "\fIGrabs an OpenCV video capture source. \fP"
+.ti -1c
+.RI "void \fBstartCapture\fP (void)"
+.br
+.RI "\fIStarts up grabbing of video frames. \fP"
+.ti -1c
+.RI "QImage * \fBIpl2QImage\fP (const IplImage *img)"
+.br
+.RI "\fIConverts from the OpenCV IplImage data structure to a QImage. \fP"
+.in -1c
+.SS "Private Attributes"
+
+.in +1c
+.ti -1c
+.RI "CvCapture * \fBcapture\fP"
+.br
+.ti -1c
+.RI "QTimer * \fBframetimer\fP"
+.br
+.ti -1c
+.RI "QImage * \fBnextFrame\fP"
+.br
+.ti -1c
+.RI "QLabel * \fBcanvas\fP"
+.br
+.ti -1c
+.RI "QVBoxLayout * \fBlayout\fP"
+.br
+.ti -1c
+.RI "QPushButton * \fBtrigger\fP"
+.br
+.ti -1c
+.RI "bool \fBtrigger_active\fP"
+.br
+.in -1c
+.SH "Detailed Description"
+.PP
+Definition at line 29 of file qopencamwidget.h.
+.SH "Constructor & Destructor Documentation"
+.PP
+.SS "QOpenCamWidget::QOpenCamWidget (QWidget * parent = \fC0\fP)"
+.PP
+Consctructs a QWidget based widget for displaying video coming from an OpenCV capture source.
+.PP
+Including webcam data in a Qt application can be problematic, at least as long as Phonon does not support webcams, and the Phonon GStreamer backend only supports simple pipelines.
+.PP
+This class solves the complexity of adding a webcam view, by using the cross-platform available OpenCV library.
+.PP
+Limitations, i.e. reasons to read this code and reimplement, are: saving or streaming video is not really available (unless you do repeated timer-triggered connections to the startSnap slot), the widget size is identical to the video source dimensions (it resizes the wodget using setMinimuSize to the video dimensions, and does not handle resizing to sizes above this dimension.
+.PP
+A brief summary of how to use this class:
+.PP
+.nf
+ QOpenCamWidget *cw = new QOpenCamWidget(this);
+ if ( cw->grabCapture(-1) ) {
+ cw->setSnapshotVisible(true);
+ cw->startCapture();
+ }
+ connect( cw, SIGNAL(imageReady(QImage)), this, SLOT(saveImage(QImage)));
+
+.fi
+.PP
+.PP
+\fBParameters:\fP
+.RS 4
+\fI*parent\fP The parent widget containing this widget, defaults to NULL.
+.RE
+.PP
+
+.PP
+Definition at line 60 of file qopencamwidget.cpp.
+.PP
+References canvas, frametimer, layout, nextFrame, trigger, and trigger_active.
+.SS "QOpenCamWidget::~QOpenCamWidget (void)"
+.PP
+Definition at line 88 of file qopencamwidget.cpp.
+.PP
+References canvas, capture, and trigger.
+.SH "Member Function Documentation"
+.PP
+.SS "void QOpenCamWidget::paintEvent (QPaintEvent * event)"
+.PP
+A paint event is a request to repaint all or part of a widget.
+.PP
+It can happen for one of the following reasons:
+.PP
+.PD 0
+.IP "\(bu" 2
+repaint() or update() was invoked,
+.IP "\(bu" 2
+the widget was obscured and has now been uncovered, or
+.IP "\(bu" 2
+many other reasons.
+.PP
+\fBQOpenCamWidget\fP uses the paintEvent to draw each frame onto the screen. The paintEvent itself is regularily triggered by explicit update() calls in \fBQOpenCamWidget::grabFrame()\fP.
+.PP
+Definition at line 144 of file qopencamwidget.cpp.
+.PP
+References canvas, and nextFrame.
+.SS "void QOpenCamWidget::setSnapshotVisible (bool visible)"
+.PP
+Changes the visibility of the optional built-in 'Take snapshot' button.
+.PP
+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 \fBQOpenCamWidget::startSnap\fP to be triggered when clicked.
+.PP
+\fBParameters:\fP
+.RS 4
+\fIvisible\fP True makes the button display, and trigger, false turns the feature off. False, i.e. no button, is default.
+.RE
+.PP
+
+.PP
+Definition at line 110 of file qopencamwidget.cpp.
+.PP
+References layout, startSnap(), trigger, and trigger_active.
+.PP
+Referenced by View::View().
+.SS "bool QOpenCamWidget::grabCapture (int source)"
+.PP
+Grabs an OpenCV video capture source.
+.PP
+By grabbing a source, it is meant to open the capture source, and have it ready to start streaming/capturing frames. Returns true on success, false on error. The grabCapture is separated from the constructor and/or frame-grabbing, so that you may do the error-checking you really should do before proceeding.
+.PP
+\fBParameters:\fP
+.RS 4
+\fIsource\fP The OpenCV capture source enumeration index to open
+.RE
+.PP
+
+.PP
+Definition at line 183 of file qopencamwidget.cpp.
+.PP
+References canvas, and capture.
+.PP
+Referenced by View::View().
+.SS "void QOpenCamWidget::startCapture (void)"
+.PP
+Starts up grabbing of video frames.
+.PP
+The actual grabbing and displaying of video frames is performed by a QTimer triggering the SLOT \fBQOpenCamWidget::grabFrame()\fP. \fBstartCapture()\fP sets up the timer running this captureFrame loop.
+.PP
+The SLOT \fBQOpenCamWidget::startSnap()\fP is used to get image frames out from the widget for other uses, like saving or processing. This function relies on the timer created and configured by \fBstartCapture()\fP, and as such, this function is the only permitted way to start the actual capture/streaming of video from the source.
+.PP
+Definition at line 217 of file qopencamwidget.cpp.
+.PP
+References frametimer, grabFrame(), and trigger.
+.PP
+Referenced by View::View().
+.SS "QImage * QOpenCamWidget::Ipl2QImage (const IplImage * img)"
+.PP
+Converts from the OpenCV IplImage data structure to a QImage.
+.PP
+OpenCV uses a data strcuture calles IplImage, optimized for computer vision image processing tasks. This code was adapted from kcamwidget.cpp, part of the KDE SVN at playground/multimedia/kcam/kcamwidget.cpp
+.PP
+In regard that the IplImage can be forced into a format that aligns well with a RBG888-format, the conversion becomes one of the shortes, simples IplImage->QImage I've seen.
+.PP
+\fBParameters:\fP
+.RS 4
+\fI*img\fP The IplImage to be converted to a QImage.
+.RE
+.PP
+
+.PP
+Definition at line 241 of file qopencamwidget.cpp.
+.PP
+Referenced by grabFrame().
+.SS "void QOpenCamWidget::grabFrame (void)\fC [slot]\fP"
+.PP
+Grabs a frame and causes an update() when triggered.
+.PP
+This is the SLOT that actually reads the video source and causes the widget to display live video. Preferably this slot will never be called my any other signal that a timeout() on the frametimer, which is controlled by \fBQOpenCamWidget::startCapture()\fP
+.PP
+Definition at line 266 of file qopencamwidget.cpp.
+.PP
+References capture, Ipl2QImage(), and nextFrame.
+.PP
+Referenced by startCapture().
+.SS "void QOpenCamWidget::startSnap (void)\fC [slot]\fP"
+.PP
+Trigger this slot to save a frame from the widget.
+.PP
+When this slot is triggered, the widgets capture loop is temporarily stopped, and the last displayed frame is 'captured', and made available through the emitting of the class imageReady SIGNAL.
+.PP
+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.
+.PP
+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.
+.PP
+Definition at line 306 of file qopencamwidget.cpp.
+.PP
+References frametimer, imageReady(), and nextFrame.
+.PP
+Referenced by setSnapshotVisible().
+.SS "void QOpenCamWidget::imageReady (QImage snapshot)\fC [signal]\fP"
+.PP
+Referenced by startSnap().
+.SH "Member Data Documentation"
+.PP
+.SS "CvCapture* \fBQOpenCamWidget::capture\fP\fC [private]\fP"
+.PP
+Definition at line 35 of file qopencamwidget.h.
+.PP
+Referenced by grabCapture(), grabFrame(), and ~QOpenCamWidget().
+.SS "QTimer* \fBQOpenCamWidget::frametimer\fP\fC [private]\fP"
+.PP
+Definition at line 36 of file qopencamwidget.h.
+.PP
+Referenced by QOpenCamWidget(), startCapture(), and startSnap().
+.SS "QImage* \fBQOpenCamWidget::nextFrame\fP\fC [private]\fP"
+.PP
+Definition at line 37 of file qopencamwidget.h.
+.PP
+Referenced by grabFrame(), paintEvent(), QOpenCamWidget(), and startSnap().
+.SS "QLabel* \fBQOpenCamWidget::canvas\fP\fC [private]\fP"
+.PP
+Definition at line 39 of file qopencamwidget.h.
+.PP
+Referenced by grabCapture(), paintEvent(), QOpenCamWidget(), and ~QOpenCamWidget().
+.SS "QVBoxLayout* \fBQOpenCamWidget::layout\fP\fC [private]\fP"
+.PP
+Definition at line 40 of file qopencamwidget.h.
+.PP
+Referenced by QOpenCamWidget(), and setSnapshotVisible().
+.SS "QPushButton* \fBQOpenCamWidget::trigger\fP\fC [private]\fP"
+.PP
+Definition at line 41 of file qopencamwidget.h.
+.PP
+Referenced by QOpenCamWidget(), setSnapshotVisible(), startCapture(), and ~QOpenCamWidget().
+.SS "bool \fBQOpenCamWidget::trigger_active\fP\fC [private]\fP"
+.PP
+Definition at line 42 of file qopencamwidget.h.
+.PP
+Referenced by QOpenCamWidget(), and setSnapshotVisible().
+
+.SH "Author"
+.PP
+Generated automatically by Doxygen for QOpenCamWidget from the source code.
diff --git a/doc/man/man3/View.3 b/doc/man/man3/View.3
new file mode 100644
index 0000000..192b38a
--- /dev/null
+++ b/doc/man/man3/View.3
@@ -0,0 +1,51 @@
+.TH "View" 3 "11 Jun 2009" "QOpenCamWidget" \" -*- nroff -*-
+.ad l
+.nh
+.SH NAME
+View \-
+.SH SYNOPSIS
+.br
+.PP
+\fC#include \fP
+.PP
+.SS "Public Slots"
+
+.in +1c
+.ti -1c
+.RI "void \fBsaveImage\fP (QImage image)"
+.br
+.in -1c
+.SS "Public Member Functions"
+
+.in +1c
+.ti -1c
+.RI "\fBView\fP (QWidget *parent=0)"
+.br
+.ti -1c
+.RI "\fB~View\fP (void)"
+.br
+.in -1c
+.SH "Detailed Description"
+.PP
+Definition at line 5 of file view.h.
+.SH "Constructor & Destructor Documentation"
+.PP
+.SS "View::View (QWidget * parent = \fC0\fP)"
+.PP
+Definition at line 32 of file view.cpp.
+.PP
+References QOpenCamWidget::grabCapture(), saveImage(), QOpenCamWidget::setSnapshotVisible(), and QOpenCamWidget::startCapture().
+.SS "View::~View (void)"
+.PP
+Definition at line 74 of file view.cpp.
+.SH "Member Function Documentation"
+.PP
+.SS "void View::saveImage (QImage image)\fC [slot]\fP"
+.PP
+Definition at line 78 of file view.cpp.
+.PP
+Referenced by View().
+
+.SH "Author"
+.PP
+Generated automatically by Doxygen for QOpenCamWidget from the source code.
diff --git a/doc/man/man3/main.cpp.3 b/doc/man/man3/main.cpp.3
new file mode 100644
index 0000000..d14a23d
--- /dev/null
+++ b/doc/man/man3/main.cpp.3
@@ -0,0 +1,28 @@
+.TH "main.cpp" 3 "11 Jun 2009" "QOpenCamWidget" \" -*- nroff -*-
+.ad l
+.nh
+.SH NAME
+main.cpp \-
+.SH SYNOPSIS
+.br
+.PP
+\fC#include \fP
+.br
+\fC#include 'view.h'\fP
+.br
+
+.SS "Functions"
+
+.in +1c
+.ti -1c
+.RI "int \fBmain\fP (int argc, char *argv[])"
+.br
+.in -1c
+.SH "Function Documentation"
+.PP
+.SS "int main (int argc, char * argv[])"
+.PP
+Definition at line 28 of file main.cpp.
+.SH "Author"
+.PP
+Generated automatically by Doxygen for QOpenCamWidget from the source code.
diff --git a/doc/man/man3/qopencamwidget.cpp.3 b/doc/man/man3/qopencamwidget.cpp.3
new file mode 100644
index 0000000..b7cc0c4
--- /dev/null
+++ b/doc/man/man3/qopencamwidget.cpp.3
@@ -0,0 +1,14 @@
+.TH "qopencamwidget.cpp" 3 "11 Jun 2009" "QOpenCamWidget" \" -*- nroff -*-
+.ad l
+.nh
+.SH NAME
+qopencamwidget.cpp \-
+.SH SYNOPSIS
+.br
+.PP
+\fC#include 'qopencamwidget.h'\fP
+.br
+
+.SH "Author"
+.PP
+Generated automatically by Doxygen for QOpenCamWidget from the source code.
diff --git a/doc/man/man3/qopencamwidget.h.3 b/doc/man/man3/qopencamwidget.h.3
new file mode 100644
index 0000000..c9c487d
--- /dev/null
+++ b/doc/man/man3/qopencamwidget.h.3
@@ -0,0 +1,25 @@
+.TH "qopencamwidget.h" 3 "11 Jun 2009" "QOpenCamWidget" \" -*- nroff -*-
+.ad l
+.nh
+.SH NAME
+qopencamwidget.h \-
+.SH SYNOPSIS
+.br
+.PP
+\fC#include \fP
+.br
+\fC#include \fP
+.br
+\fC#include \fP
+.br
+
+.SS "Classes"
+
+.in +1c
+.ti -1c
+.RI "class \fBQOpenCamWidget\fP"
+.br
+.in -1c
+.SH "Author"
+.PP
+Generated automatically by Doxygen for QOpenCamWidget from the source code.
diff --git a/doc/man/man3/view.cpp.3 b/doc/man/man3/view.cpp.3
new file mode 100644
index 0000000..8a03c21
--- /dev/null
+++ b/doc/man/man3/view.cpp.3
@@ -0,0 +1,16 @@
+.TH "view.cpp" 3 "11 Jun 2009" "QOpenCamWidget" \" -*- nroff -*-
+.ad l
+.nh
+.SH NAME
+view.cpp \-
+.SH SYNOPSIS
+.br
+.PP
+\fC#include 'view.h'\fP
+.br
+\fC#include 'qopencamwidget.h'\fP
+.br
+
+.SH "Author"
+.PP
+Generated automatically by Doxygen for QOpenCamWidget from the source code.
diff --git a/doc/man/man3/view.h.3 b/doc/man/man3/view.h.3
new file mode 100644
index 0000000..2014d1b
--- /dev/null
+++ b/doc/man/man3/view.h.3
@@ -0,0 +1,21 @@
+.TH "view.h" 3 "11 Jun 2009" "QOpenCamWidget" \" -*- nroff -*-
+.ad l
+.nh
+.SH NAME
+view.h \-
+.SH SYNOPSIS
+.br
+.PP
+\fC#include \fP
+.br
+
+.SS "Classes"
+
+.in +1c
+.ti -1c
+.RI "class \fBView\fP"
+.br
+.in -1c
+.SH "Author"
+.PP
+Generated automatically by Doxygen for QOpenCamWidget from the source code.
diff --git a/doc/rtf/refman.rtf b/doc/rtf/refman.rtf
new file mode 100644
index 0000000..aff5083
--- /dev/null
+++ b/doc/rtf/refman.rtf
@@ -0,0 +1,1407 @@
+{\rtf1\ansi\ansicpg1252\uc1 \deff0\deflang1033\deflangfe1033
+{\comment Begining font list}
+{\fonttbl {\f0\froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}
+{\f1\fswiss\fcharset0\fprq2{\*\panose 020b0604020202020204}Arial;}
+{\f2\fmodern\fcharset0\fprq1{\*\panose 02070309020205020404}Courier New;}
+{\f3\froman\fcharset2\fprq2{\*\panose 05050102010706020507}Symbol;}
+}
+{\comment begin colors}
+{\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0;\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;\red128\green0\blue128;\red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128;\red192\green192\blue192;}
+{\comment Beginning style list}
+{\stylesheet
+{\widctlpar\adjustright \fs20\cgrid \snext0 Normal;}
+{\s1\sb240\sa60\keepn\widctlpar\adjustright \b\f1\fs36\kerning36\cgrid \sbasedon0 \snext0 heading 1;}
+{\s2\sb240\sa60\keepn\widctlpar\adjustright \b\f1\fs28\kerning28\cgrid \sbasedon0 \snext0 heading 2;}
+{\s3\sb240\sa60\keepn\widctlpar\adjustright \b\f1\cgrid \sbasedon0 \snext0 heading 3;}
+{\s4\sb240\sa60\keepn\widctlpar\adjustright \b\f1\fs20\cgrid \sbasedon0 \snext0 heading 4;}{\*\cs10 \additive Default Paragraph Font;}
+{\s5\sb90\sa30\keepn\widctlpar\adjustright \b\f1\fs20\cgrid \sbasedon0 \snext0 heading 5;}{\*\cs10 \additive Default Paragraph Font;}
+{\s15\qc\sb240\sa60\widctlpar\outlinelevel0\adjustright \b\f1\fs32\kerning28\cgrid \sbasedon0 \snext15 Title;}
+{\s16\qc\sa60\widctlpar\outlinelevel1\adjustright \f1\cgrid \sbasedon0 \snext16 Subtitle;}
+{\s17\sa60\sb30\widctlpar\qj \fs22\cgrid \sbasedon0 \snext17 BodyText;}
+{\s18\widctlpar\fs22\cgrid \sbasedon0 \snext18 DenseText;}
+{\s28\widctlpar\tqc\tx4320\tqr\tx8640\adjustright \fs20\cgrid \sbasedon0 \snext28 header;}
+{\s29\widctlpar\tqc\tx4320\tqr\tx8640\qr\adjustright \fs20\cgrid \sbasedon0 \snext29 footer;}
+{\s30\li360\sa60\sb120\keepn\widctlpar\adjustright \b\f1\fs20\cgrid \sbasedon0 \snext30 GroupHeader;}
+{\s40\li0\widctlpar\adjustright \shading1000\cbpat8 \f2\fs16\cgrid \sbasedon0 \snext41 Code Example 0;}
+{\s41\li360\widctlpar\adjustright \shading1000\cbpat8 \f2\fs16\cgrid \sbasedon0 \snext42 Code Example 1;}
+{\s42\li720\widctlpar\adjustright \shading1000\cbpat8 \f2\fs16\cgrid \sbasedon0 \snext43 Code Example 2;}
+{\s43\li1080\widctlpar\adjustright \shading1000\cbpat8 \f2\fs16\cgrid \sbasedon0 \snext44 Code Example 3;}
+{\s44\li1440\widctlpar\adjustright \shading1000\cbpat8 \f2\fs16\cgrid \sbasedon0 \snext45 Code Example 4;}
+{\s45\li1800\widctlpar\adjustright \shading1000\cbpat8 \f2\fs16\cgrid \sbasedon0 \snext46 Code Example 5;}
+{\s46\li2160\widctlpar\adjustright \shading1000\cbpat8 \f2\fs16\cgrid \sbasedon0 \snext47 Code Example 6;}
+{\s47\li2520\widctlpar\adjustright \shading1000\cbpat8 \f2\fs16\cgrid \sbasedon0 \snext48 Code Example 7;}
+{\s48\li2880\widctlpar\adjustright \shading1000\cbpat8 \f2\fs16\cgrid \sbasedon0 \snext49 Code Example 8;}
+{\s49\li3240\widctlpar\adjustright \shading1000\cbpat8 \f2\fs16\cgrid \sbasedon0 \snext49 Code Example 9;}
+{\s50\li0\sa60\sb30\qj\widctlpar\qj\adjustright \fs20\cgrid \sbasedon0 \snext51 List Continue 0;}
+{\s51\li360\sa60\sb30\qj\widctlpar\qj\adjustright \fs20\cgrid \sbasedon0 \snext52 List Continue 1;}
+{\s52\li720\sa60\sb30\qj\widctlpar\qj\adjustright \fs20\cgrid \sbasedon0 \snext53 List Continue 2;}
+{\s53\li1080\sa60\sb30\qj\widctlpar\qj\adjustright \fs20\cgrid \sbasedon0 \snext54 List Continue 3;}
+{\s54\li1440\sa60\sb30\qj\widctlpar\qj\adjustright \fs20\cgrid \sbasedon0 \snext55 List Continue 4;}
+{\s55\li1800\sa60\sb30\qj\widctlpar\qj\adjustright \fs20\cgrid \sbasedon0 \snext56 List Continue 5;}
+{\s56\li2160\sa60\sb30\qj\widctlpar\qj\adjustright \fs20\cgrid \sbasedon0 \snext57 List Continue 6;}
+{\s57\li2520\sa60\sb30\qj\widctlpar\qj\adjustright \fs20\cgrid \sbasedon0 \snext58 List Continue 7;}
+{\s58\li2880\sa60\sb30\qj\widctlpar\qj\adjustright \fs20\cgrid \sbasedon0 \snext59 List Continue 8;}
+{\s59\li3240\sa60\sb30\qj\widctlpar\qj\adjustright \fs20\cgrid \sbasedon0 \snext59 List Continue 9;}
+{\s60\li0\widctlpar\ql\adjustright \fs20\cgrid \sbasedon0 \snext61 DescContinue 0;}
+{\s61\li360\widctlpar\ql\adjustright \fs20\cgrid \sbasedon0 \snext62 DescContinue 1;}
+{\s62\li720\widctlpar\ql\adjustright \fs20\cgrid \sbasedon0 \snext63 DescContinue 2;}
+{\s63\li1080\widctlpar\ql\adjustright \fs20\cgrid \sbasedon0 \snext64 DescContinue 3;}
+{\s64\li1440\widctlpar\ql\adjustright \fs20\cgrid \sbasedon0 \snext65 DescContinue 4;}
+{\s65\li1800\widctlpar\ql\adjustright \fs20\cgrid \sbasedon0 \snext66 DescContinue 5;}
+{\s66\li2160\widctlpar\ql\adjustright \fs20\cgrid \sbasedon0 \snext67 DescContinue 6;}
+{\s67\li2520\widctlpar\ql\adjustright \fs20\cgrid \sbasedon0 \snext68 DescContinue 7;}
+{\s68\li2880\widctlpar\ql\adjustright \fs20\cgrid \sbasedon0 \snext69 DescContinue 8;}
+{\s69\li3240\widctlpar\ql\adjustright \fs20\cgrid \sbasedon0 \snext69 DescContinue 9;}
+{\s70\li0\sa30\sb30\widctlpar\tqr\tldot\tx8640\adjustright \fs20\cgrid \sbasedon0 \snext81 LatexTOC 0;}
+{\s71\li360\sa27\sb27\widctlpar\tqr\tldot\tx8640\adjustright \fs20\cgrid \sbasedon0 \snext82 LatexTOC 1;}
+{\s72\li720\sa24\sb24\widctlpar\tqr\tldot\tx8640\adjustright \fs20\cgrid \sbasedon0 \snext83 LatexTOC 2;}
+{\s73\li1080\sa21\sb21\widctlpar\tqr\tldot\tx8640\adjustright \fs20\cgrid \sbasedon0 \snext84 LatexTOC 3;}
+{\s74\li1440\sa18\sb18\widctlpar\tqr\tldot\tx8640\adjustright \fs20\cgrid \sbasedon0 \snext85 LatexTOC 4;}
+{\s75\li1800\sa15\sb15\widctlpar\tqr\tldot\tx8640\adjustright \fs20\cgrid \sbasedon0 \snext86 LatexTOC 5;}
+{\s76\li2160\sa12\sb12\widctlpar\tqr\tldot\tx8640\adjustright \fs20\cgrid \sbasedon0 \snext87 LatexTOC 6;}
+{\s77\li2520\sa9\sb9\widctlpar\tqr\tldot\tx8640\adjustright \fs20\cgrid \sbasedon0 \snext88 LatexTOC 7;}
+{\s78\li2880\sa6\sb6\widctlpar\tqr\tldot\tx8640\adjustright \fs20\cgrid \sbasedon0 \snext89 LatexTOC 8;}
+{\s79\li3240\sa3\sb3\widctlpar\tqr\tldot\tx8640\adjustright \fs20\cgrid \sbasedon0 \snext89 LatexTOC 9;}
+{\s80\fi-360\li360\widctlpar\jclisttab\tx360{\*\pn \pnlvlbody\ilvl0\ls1\pnrnot0\pndec }\ls1\adjustright \fs20\cgrid \sbasedon0 \snext81 \sautoupd List Bullet 0;}
+{\s81\fi-360\li720\widctlpar\jclisttab\tx720{\*\pn \pnlvlbody\ilvl0\ls2\pnrnot0\pndec }\ls2\adjustright \fs20\cgrid \sbasedon0 \snext82 \sautoupd List Bullet 1;}
+{\s82\fi-360\li1080\widctlpar\jclisttab\tx1080{\*\pn \pnlvlbody\ilvl0\ls3\pnrnot0\pndec }\ls3\adjustright \fs20\cgrid \sbasedon0 \snext83 \sautoupd List Bullet 2;}
+{\s83\fi-360\li1440\widctlpar\jclisttab\tx1440{\*\pn \pnlvlbody\ilvl0\ls4\pnrnot0\pndec }\ls4\adjustright \fs20\cgrid \sbasedon0 \snext84 \sautoupd List Bullet 3;}
+{\s84\fi-360\li1800\widctlpar\jclisttab\tx1800{\*\pn \pnlvlbody\ilvl0\ls5\pnrnot0\pndec }\ls5\adjustright \fs20\cgrid \sbasedon0 \snext85 \sautoupd List Bullet 4;}
+{\s85\fi-360\li2160\widctlpar\jclisttab\tx2160{\*\pn \pnlvlbody\ilvl0\ls6\pnrnot0\pndec }\ls6\adjustright \fs20\cgrid \sbasedon0 \snext86 \sautoupd List Bullet 5;}
+{\s86\fi-360\li2520\widctlpar\jclisttab\tx2520{\*\pn \pnlvlbody\ilvl0\ls7\pnrnot0\pndec }\ls7\adjustright \fs20\cgrid \sbasedon0 \snext87 \sautoupd List Bullet 6;}
+{\s87\fi-360\li2880\widctlpar\jclisttab\tx2880{\*\pn \pnlvlbody\ilvl0\ls8\pnrnot0\pndec }\ls8\adjustright \fs20\cgrid \sbasedon0 \snext88 \sautoupd List Bullet 7;}
+{\s88\fi-360\li3240\widctlpar\jclisttab\tx3240{\*\pn \pnlvlbody\ilvl0\ls9\pnrnot0\pndec }\ls9\adjustright \fs20\cgrid \sbasedon0 \snext89 \sautoupd List Bullet 8;}
+{\s89\fi-360\li3600\widctlpar\jclisttab\tx3600{\*\pn \pnlvlbody\ilvl0\ls10\pnrnot0\pndec }\ls10\adjustright \fs20\cgrid \sbasedon0 \snext89 \sautoupd List Bullet 9;}
+{\s90\fi-360\li360\widctlpar\fs20\cgrid \sbasedon0 \snext91 \sautoupd List Enum 0;}
+{\s91\fi-360\li720\widctlpar\fs20\cgrid \sbasedon0 \snext92 \sautoupd List Enum 1;}
+{\s92\fi-360\li1080\widctlpar\fs20\cgrid \sbasedon0 \snext93 \sautoupd List Enum 2;}
+{\s93\fi-360\li1440\widctlpar\fs20\cgrid \sbasedon0 \snext94 \sautoupd List Enum 3;}
+{\s94\fi-360\li1800\widctlpar\fs20\cgrid \sbasedon0 \snext95 \sautoupd List Enum 4;}
+{\s95\fi-360\li2160\widctlpar\fs20\cgrid \sbasedon0 \snext96 \sautoupd List Enum 5;}
+{\s96\fi-360\li2520\widctlpar\fs20\cgrid \sbasedon0 \snext96 \sautoupd List Enum 5;}
+{\s97\fi-360\li2880\widctlpar\fs20\cgrid \sbasedon0 \snext98 \sautoupd List Enum 7;}
+{\s98\fi-360\li3240\widctlpar\fs20\cgrid \sbasedon0 \snext99 \sautoupd List Enum 8;}
+{\s99\fi-360\li3600\widctlpar\fs20\cgrid \sbasedon0 \snext99 \sautoupd List Enum 9;}
+}
+{\comment begin body}
+{\info
+{\title {\comment QOpenCamWidget }QOpenCamWidget}
+{\comment Generated byDoxgyen. }
+{\creatim \yr2009\mo6\dy11\hr1\min49\sec57}
+}{\comment end of infoblock}
+\pard\plain
+\sectd\pgnlcrm
+{\footer \s29\widctlpar\tqc\tx4320\tqr\tx8640\qr\adjustright \fs20\cgrid {\chpgn}}
+{\comment begin title page}
+\pard\plain \s16\qc\sa60\widctlpar\outlinelevel1\adjustright \f1\cgrid
+\vertalc\qc\par\par\par\par\par\par\par
+\pard\plain \s15\qc\sb240\sa60\widctlpar\outlinelevel0\adjustright \b\f1\fs32\kerning28\cgrid
+{\field\fldedit {\*\fldinst TITLE \\*MERGEFORMAT}{\fldrslt TITLE}}\par
+\pard\plain \s16\qc\sa60\widctlpar\outlinelevel1\adjustright \f1\cgrid
+\par
+\par\par\par\par\par\par\par\par\par\par\par\par
+\pard\plain \s16\qc\sa60\widctlpar\outlinelevel1\adjustright \f1\cgrid
+{\field\fldedit {\*\fldinst AUTHOR \\*MERGEFORMAT}{\fldrslt AUTHOR}}\par
+Version \par{\field\fldedit {\*\fldinst CREATEDATE \\*MERGEFORMAT}{\fldrslt CREATEDATE}}\par
+\page\page{\comment End title page}
+{\comment Table of contents}
+\vertalt
+\pard\plain
+\s1\sb240\sa60\keepn\widctlpar\adjustright \b\f1\fs36\kerning36\cgrid Table of Contents\par
+\pard\plain \par
+{\field\fldedit {\*\fldinst TOC \\f \\*MERGEFORMAT}{\fldrslt Table of contents}}\par
+\pard\plain
+{\comment Beginning Body of RTF Document}
+\sect \sbkpage \pgndec \pgnrestart
+\sect \sectd \sbknone
+{\footer \s29\widctlpar\tqc\tx4320\tqr\tx8640\qr\adjustright \fs20\cgrid {\chpgn}}
+
+{\comment BeginRTFChapter}
+\pard\plain \sect\sbkpage
+\s1\sb240\sa60\keepn\widctlpar\adjustright \b\f1\fs36\kerning36\cgrid
+Class Index\par \pard\plain
+{\tc \v Class Index}
+{\comment begin include annotated.rtf}
+{\comment startTitleHead}
+\pard\plain \s2\sb240\sa60\keepn\widctlpar\adjustright \b\f1\fs28\kerning28\cgrid
+Class List{\comment endTitleHead}
+\par \pard\plain
+{\comment startTextBlock}
+{
+\pard\plain \s17\sa60\sb30\widctlpar\qj \fs22\cgrid Here are the classes, structs, unions and interfaces with brief descriptions:{\comment endTextBlock}
+}
+{\comment (startIndexList)}
+{
+\par
+\pard\plain \s71\li360\sa27\sb27\widctlpar\tqr\tldot\tx8640\adjustright \fs20\cgrid
+{\comment (startIndexKey)}
+{\b {\b QOpenCamWidget}{\comment (endIndexKey)}
+{\comment (startIndexValue)}
+ {\comment (endIndexValue)}
+} \tab {\field\fldedit {\*\fldinst PAGEREF AAAAAAAAAG \\*MERGEFORMAT}{\fldrslt pagenum}}
+{\comment (newParagraph)}
+\par
+{\comment (startIndexKey)}
+{\b {\b View}{\comment (endIndexKey)}
+{\comment (startIndexValue)}
+ {\comment (endIndexValue)}
+} \tab {\field\fldedit {\*\fldinst PAGEREF AAAAAAAAAH \\*MERGEFORMAT}{\fldrslt pagenum}}
+{\comment (newParagraph)}
+\par
+{\comment (endIndexList)}
+\par}{\comment endFile}
+{\comment end include annotated.rtf}
+
+{\comment BeginRTFChapter}
+\pard\plain \sect\sbkpage
+\s1\sb240\sa60\keepn\widctlpar\adjustright \b\f1\fs36\kerning36\cgrid
+File Index\par \pard\plain
+{\tc \v File Index}
+{\comment begin include files.rtf}
+{\comment startTitleHead}
+\pard\plain \s2\sb240\sa60\keepn\widctlpar\adjustright \b\f1\fs28\kerning28\cgrid
+File List{\comment endTitleHead}
+\par \pard\plain
+{\comment startTextBlock}
+{
+\pard\plain \s17\sa60\sb30\widctlpar\qj \fs22\cgrid Here is a list of all files with brief descriptions:{\comment endTextBlock}
+}
+{\comment (startIndexList)}
+{
+\par
+\pard\plain \s71\li360\sa27\sb27\widctlpar\tqr\tldot\tx8640\adjustright \fs20\cgrid
+{\comment (startIndexKey)}
+{\b {\b main.cpp}{\comment (endIndexKey)}
+{\comment (startIndexValue)}
+ {\comment (endIndexValue)}
+} \tab {\field\fldedit {\*\fldinst PAGEREF AAAAAAAAAA \\*MERGEFORMAT}{\fldrslt pagenum}}
+{\comment (newParagraph)}
+\par
+{\comment (startIndexKey)}
+{\b {\b qopencamwidget.cpp}{\comment (endIndexKey)}
+{\comment (startIndexValue)}
+ {\comment (endIndexValue)}
+} \tab {\field\fldedit {\*\fldinst PAGEREF AAAAAAAAAC \\*MERGEFORMAT}{\fldrslt pagenum}}
+{\comment (newParagraph)}
+\par
+{\comment (startIndexKey)}
+{\b {\b qopencamwidget.h}{\comment (endIndexKey)}
+{\comment (startIndexValue)}
+ {\comment (endIndexValue)}
+} \tab {\field\fldedit {\*\fldinst PAGEREF AAAAAAAAAD \\*MERGEFORMAT}{\fldrslt pagenum}}
+{\comment (newParagraph)}
+\par
+{\comment (startIndexKey)}
+{\b {\b view.cpp}{\comment (endIndexKey)}
+{\comment (startIndexValue)}
+ {\comment (endIndexValue)}
+} \tab {\field\fldedit {\*\fldinst PAGEREF AAAAAAAAAE \\*MERGEFORMAT}{\fldrslt pagenum}}
+{\comment (newParagraph)}
+\par
+{\comment (startIndexKey)}
+{\b {\b view.h}{\comment (endIndexKey)}
+{\comment (startIndexValue)}
+ {\comment (endIndexValue)}
+} \tab {\field\fldedit {\*\fldinst PAGEREF AAAAAAAAAF \\*MERGEFORMAT}{\fldrslt pagenum}}
+{\comment (newParagraph)}
+\par
+{\comment (endIndexList)}
+\par}{\comment endFile}
+{\comment end include files.rtf}
+
+{\comment BeginRTFChapter}
+\pard\plain \sect\sbkpage
+\s1\sb240\sa60\keepn\widctlpar\adjustright \b\f1\fs36\kerning36\cgrid
+Class Documentation{\tc \v Class Documentation}
+\par \pard\plain
+{\comment begin include classQOpenCamWidget.rtf}
+{\comment startTitleHead}
+\pard\plain \s2\sb240\sa60\keepn\widctlpar\adjustright \b\f1\fs28\kerning28\cgrid
+QOpenCamWidget Class Reference{\comment endTitleHead}
+\par \pard\plain
+{\tc\tcl2 \v QOpenCamWidget}
+{\xe \v QOpenCamWidget}
+{\comment writeAnchor (classQOpenCamWidget)}
+{\bkmkstart AAAAAAAAAG}
+{\bkmkend AAAAAAAAAG}
+{\comment startTextBlock}
+{
+\pard\plain \s17\sa60\sb30\widctlpar\qj \fs22\cgrid {\f2 #include }{\comment (newParagraph)}
+\par
+{\comment (newParagraph)}
+\par
+{\comment endTextBlock}
+}
+{\comment startGroupHeader}
+\pard\plain \s3\sb240\sa60\keepn\widctlpar\adjustright \b\f1\cgrid
+Public Slots{\comment endGroupHeader}
+\par
+\pard\plain
+
+{\comment (startMemberList) }
+{
+{\comment startMemberItem }
+\pard\plain \s80\fi-360\li360\widctlpar\jclisttab\tx360{\*\pn \pnlvlbody\ilvl0\ls1\pnrnot0\pndec }\ls1\adjustright \fs20\cgrid
+void {\b grabFrame} (void){\comment endMemberItem }
+{\comment (newParagraph)}
+\par
+{\comment (startMemberDescription)}
+{
+\pard\plain \s51\li360\sa60\sb30\qj\widctlpar\qj\adjustright \fs20\cgrid {\i {\s17\sa60\sb30\widctlpar\qj \fs22\cgrid
+Grabs a frame and causes an update() when triggered. \par
+}{\comment (endMemberDescription)}
+}}
+{\comment startMemberItem }
+\pard\plain \s80\fi-360\li360\widctlpar\jclisttab\tx360{\*\pn \pnlvlbody\ilvl0\ls1\pnrnot0\pndec }\ls1\adjustright \fs20\cgrid
+void {\b startSnap} (){\comment endMemberItem }
+{\comment (newParagraph)}
+\par
+{\comment (startMemberDescription)}
+{
+\pard\plain \s51\li360\sa60\sb30\qj\widctlpar\qj\adjustright \fs20\cgrid {\i {\s17\sa60\sb30\widctlpar\qj \fs22\cgrid
+Trigger this slot to save a frame from the widget. \par
+}{\comment (endMemberDescription)}
+}}
+{\comment (endMemberList) }
+}
+{\comment startGroupHeader}
+\pard\plain \s3\sb240\sa60\keepn\widctlpar\adjustright \b\f1\cgrid
+Signals{\comment endGroupHeader}
+\par
+\pard\plain
+
+{\comment (startMemberList) }
+{
+{\comment startMemberItem }
+\pard\plain \s80\fi-360\li360\widctlpar\jclisttab\tx360{\*\pn \pnlvlbody\ilvl0\ls1\pnrnot0\pndec }\ls1\adjustright \fs20\cgrid
+void {\b imageReady} (QImage snapshot){\comment endMemberItem }
+{\comment (newParagraph)}
+\par
+{\comment (endMemberList) }
+}
+{\comment startGroupHeader}
+\pard\plain \s3\sb240\sa60\keepn\widctlpar\adjustright \b\f1\cgrid
+Public Member Functions{\comment endGroupHeader}
+\par
+\pard\plain
+
+{\comment (startMemberList) }
+{
+{\comment startMemberItem }
+\pard\plain \s80\fi-360\li360\widctlpar\jclisttab\tx360{\*\pn \pnlvlbody\ilvl0\ls1\pnrnot0\pndec }\ls1\adjustright \fs20\cgrid
+{\b QOpenCamWidget} (QWidget *parent=0){\comment endMemberItem }
+{\comment (newParagraph)}
+\par
+{\comment (startMemberDescription)}
+{
+\pard\plain \s51\li360\sa60\sb30\qj\widctlpar\qj\adjustright \fs20\cgrid {\i {\s17\sa60\sb30\widctlpar\qj \fs22\cgrid
+Consctructs a QWidget based widget for displaying video coming from an OpenCV capture source. \par
+}{\comment (endMemberDescription)}
+}}
+{\comment startMemberItem }
+\pard\plain \s80\fi-360\li360\widctlpar\jclisttab\tx360{\*\pn \pnlvlbody\ilvl0\ls1\pnrnot0\pndec }\ls1\adjustright \fs20\cgrid
+{\b ~QOpenCamWidget} (void){\comment endMemberItem }
+{\comment (newParagraph)}
+\par
+{\comment startMemberItem }
+\pard\plain \s80\fi-360\li360\widctlpar\jclisttab\tx360{\*\pn \pnlvlbody\ilvl0\ls1\pnrnot0\pndec }\ls1\adjustright \fs20\cgrid
+void {\b paintEvent} (QPaintEvent *event){\comment endMemberItem }
+{\comment (newParagraph)}
+\par
+{\comment (startMemberDescription)}
+{
+\pard\plain \s51\li360\sa60\sb30\qj\widctlpar\qj\adjustright \fs20\cgrid {\i {\s17\sa60\sb30\widctlpar\qj \fs22\cgrid
+A paint event is a request to repaint all or part of a widget. \par
+}{\comment (endMemberDescription)}
+}}
+{\comment startMemberItem }
+\pard\plain \s80\fi-360\li360\widctlpar\jclisttab\tx360{\*\pn \pnlvlbody\ilvl0\ls1\pnrnot0\pndec }\ls1\adjustright \fs20\cgrid
+void {\b setSnapshotVisible} (bool visible){\comment endMemberItem }
+{\comment (newParagraph)}
+\par
+{\comment (startMemberDescription)}
+{
+\pard\plain \s51\li360\sa60\sb30\qj\widctlpar\qj\adjustright \fs20\cgrid {\i {\s17\sa60\sb30\widctlpar\qj \fs22\cgrid
+Changes the visibility of the optional built-in "Take snapshot" button. \par
+}{\comment (endMemberDescription)}
+}}
+{\comment startMemberItem }
+\pard\plain \s80\fi-360\li360\widctlpar\jclisttab\tx360{\*\pn \pnlvlbody\ilvl0\ls1\pnrnot0\pndec }\ls1\adjustright \fs20\cgrid
+bool {\b grabCapture} (int source){\comment endMemberItem }
+{\comment (newParagraph)}
+\par
+{\comment (startMemberDescription)}
+{
+\pard\plain \s51\li360\sa60\sb30\qj\widctlpar\qj\adjustright \fs20\cgrid {\i {\s17\sa60\sb30\widctlpar\qj \fs22\cgrid
+Grabs an OpenCV video capture source. \par
+}{\comment (endMemberDescription)}
+}}
+{\comment startMemberItem }
+\pard\plain \s80\fi-360\li360\widctlpar\jclisttab\tx360{\*\pn \pnlvlbody\ilvl0\ls1\pnrnot0\pndec }\ls1\adjustright \fs20\cgrid
+void {\b startCapture} (void){\comment endMemberItem }
+{\comment (newParagraph)}
+\par
+{\comment (startMemberDescription)}
+{
+\pard\plain \s51\li360\sa60\sb30\qj\widctlpar\qj\adjustright \fs20\cgrid {\i {\s17\sa60\sb30\widctlpar\qj \fs22\cgrid
+Starts up grabbing of video frames. \par
+}{\comment (endMemberDescription)}
+}}
+{\comment startMemberItem }
+\pard\plain \s80\fi-360\li360\widctlpar\jclisttab\tx360{\*\pn \pnlvlbody\ilvl0\ls1\pnrnot0\pndec }\ls1\adjustright \fs20\cgrid
+QImage * {\b Ipl2QImage} (const IplImage *img){\comment endMemberItem }
+{\comment (newParagraph)}
+\par
+{\comment (startMemberDescription)}
+{
+\pard\plain \s51\li360\sa60\sb30\qj\widctlpar\qj\adjustright \fs20\cgrid {\i {\s17\sa60\sb30\widctlpar\qj \fs22\cgrid
+Converts from the OpenCV IplImage data structure to a QImage. \par
+}{\comment (endMemberDescription)}
+}}
+{\comment (endMemberList) }
+}
+{\comment startGroupHeader}
+\pard\plain \s3\sb240\sa60\keepn\widctlpar\adjustright \b\f1\cgrid
+Private Attributes{\comment endGroupHeader}
+\par
+\pard\plain
+
+{\comment (startMemberList) }
+{
+{\comment startMemberItem }
+\pard\plain \s80\fi-360\li360\widctlpar\jclisttab\tx360{\*\pn \pnlvlbody\ilvl0\ls1\pnrnot0\pndec }\ls1\adjustright \fs20\cgrid
+CvCapture * {\b capture}{\comment endMemberItem }
+{\comment (newParagraph)}
+\par
+{\comment startMemberItem }
+\pard\plain \s80\fi-360\li360\widctlpar\jclisttab\tx360{\*\pn \pnlvlbody\ilvl0\ls1\pnrnot0\pndec }\ls1\adjustright \fs20\cgrid
+QTimer * {\b frametimer}{\comment endMemberItem }
+{\comment (newParagraph)}
+\par
+{\comment startMemberItem }
+\pard\plain \s80\fi-360\li360\widctlpar\jclisttab\tx360{\*\pn \pnlvlbody\ilvl0\ls1\pnrnot0\pndec }\ls1\adjustright \fs20\cgrid
+QImage * {\b nextFrame}{\comment endMemberItem }
+{\comment (newParagraph)}
+\par
+{\comment startMemberItem }
+\pard\plain \s80\fi-360\li360\widctlpar\jclisttab\tx360{\*\pn \pnlvlbody\ilvl0\ls1\pnrnot0\pndec }\ls1\adjustright \fs20\cgrid
+QLabel * {\b canvas}{\comment endMemberItem }
+{\comment (newParagraph)}
+\par
+{\comment startMemberItem }
+\pard\plain \s80\fi-360\li360\widctlpar\jclisttab\tx360{\*\pn \pnlvlbody\ilvl0\ls1\pnrnot0\pndec }\ls1\adjustright \fs20\cgrid
+QVBoxLayout * {\b layout}{\comment endMemberItem }
+{\comment (newParagraph)}
+\par
+{\comment startMemberItem }
+\pard\plain \s80\fi-360\li360\widctlpar\jclisttab\tx360{\*\pn \pnlvlbody\ilvl0\ls1\pnrnot0\pndec }\ls1\adjustright \fs20\cgrid
+QPushButton * {\b trigger}{\comment endMemberItem }
+{\comment (newParagraph)}
+\par
+{\comment startMemberItem }
+\pard\plain \s80\fi-360\li360\widctlpar\jclisttab\tx360{\*\pn \pnlvlbody\ilvl0\ls1\pnrnot0\pndec }\ls1\adjustright \fs20\cgrid
+bool {\b trigger_active}{\comment endMemberItem }
+{\comment (newParagraph)}
+\par
+{\comment (endMemberList) }
+}
+{\comment (rtfwriteRuler_thin)}
+{\pard\widctlpar\brdrb\brdrs\brdrw5\brsp20 \adjustright \par}
+{\comment startGroupHeader}
+\pard\plain \s3\sb240\sa60\keepn\widctlpar\adjustright \b\f1\cgrid
+Detailed Description{\comment endGroupHeader}
+\par
+\pard\plain
+{\comment startTextBlock}
+{
+\pard\plain \s17\sa60\sb30\widctlpar\qj \fs22\cgrid {\comment startParagraph}
+{
+Definition at line 29 of file qopencamwidget.h.{\comment endParagraph}
+}\par
+{\comment endTextBlock}
+}
+{\comment (rtfwriteRuler_thin)}
+{\pard\widctlpar\brdrb\brdrs\brdrw5\brsp20 \adjustright \par}
+{\comment startGroupHeader}
+\pard\plain \s3\sb240\sa60\keepn\widctlpar\adjustright \b\f1\cgrid
+Constructor & Destructor Documentation{\comment endGroupHeader}
+\par
+\pard\plain
+{\comment startDoxyAnchor}
+{\comment startMemberDoc}
+{\xe \v QOpenCamWidget\:QOpenCamWidget}
+{\xe \v QOpenCamWidget\:QOpenCamWidget}
+\pard\plain \s4\sb240\sa60\keepn\widctlpar\adjustright \b\f1\fs20\cgrid {
+{\b
+QOpenCamWidget::QOpenCamWidget ({\comment (startParameterList)}
+QWidget * {\i parent} = {\f2 0}){\comment endMemberDoc}
+}
+}{\comment (newParagraph)}
+\par
+{\comment endDoxyAnchor}
+{\bkmkstart AAAAAAAAAI}
+{\bkmkend AAAAAAAAAI}
+{\comment (startIndent) }
+{
+\pard\plain \s51\li360\sa60\sb30\qj\widctlpar\qj\adjustright \fs20\cgrid
+{\s17\sa60\sb30\widctlpar\qj \fs22\cgrid
+Consctructs a QWidget based widget for displaying video coming from an OpenCV capture source. \par
+}{\s17\sa60\sb30\widctlpar\qj \fs22\cgrid
+Including webcam data in a Qt application can be problematic, at least as long as Phonon does not support webcams, and the Phonon GStreamer backend only supports simple pipelines.\par
+This class solves the complexity of adding a webcam view, by using the cross-platform available OpenCV library.\par
+Limitations, i.e. reasons to read this code and reimplement, are: saving or streaming video is not really available (unless you do repeated timer-triggered connections to the startSnap slot), the widget size is identical to the video source dimensions (it resizes the wodget using setMinimuSize to the video dimensions, and does not handle resizing to sizes above this dimension.\par
+A brief summary of how to use this class: {
+\par
+\pard\plain \s41\li360\widctlpar\adjustright \shading1000\cbpat8 \f2\fs16\cgrid QOpenCamWidget *cw = new QOpenCamWidget(this);{\comment (lineBreak)}
+\par
+ if ( cw->grabCapture(-1) ) \{{\comment (lineBreak)}
+\par
+ cw->setSnapshotVisible(true);{\comment (lineBreak)}
+\par
+ cw->startCapture();{\comment (lineBreak)}
+\par
+ \}{\comment (lineBreak)}
+\par
+ connect( cw, SIGNAL(imageReady(QImage)), this, SLOT(saveImage(QImage)));{\comment (lineBreak)}
+\par
+}
+\par
+{{\s5\sb90\sa30\keepn\widctlpar\adjustright \b\f1\fs20\cgrid
+Parameters:\par}
+\pard\plain \s62\li720\widctlpar\ql\adjustright \fs20\cgrid {\i *parent} The parent widget containing this widget, defaults to NULL. \par
+}
+}{\comment startParagraph}
+{
+Definition at line 60 of file qopencamwidget.cpp.{\comment endParagraph}
+}\par
+{\comment startParagraph}
+{
+References canvas, frametimer, layout, nextFrame, trigger, and trigger_active.{\comment endParagraph}
+}\par
+}
+{\comment startDoxyAnchor}
+{\comment startMemberDoc}
+{\xe \v ~QOpenCamWidget\:QOpenCamWidget}
+{\xe \v QOpenCamWidget\:~QOpenCamWidget}
+\pard\plain \s4\sb240\sa60\keepn\widctlpar\adjustright \b\f1\fs20\cgrid {
+{\b
+QOpenCamWidget::~QOpenCamWidget ({\comment (startParameterList)}
+void){\comment endMemberDoc}
+}
+}{\comment (newParagraph)}
+\par
+{\comment endDoxyAnchor}
+{\bkmkstart AAAAAAAAAJ}
+{\bkmkend AAAAAAAAAJ}
+{\comment (startIndent) }
+{
+\pard\plain \s51\li360\sa60\sb30\qj\widctlpar\qj\adjustright \fs20\cgrid
+{\comment startParagraph}
+{\comment (newParagraph)}
+\par
+{
+Definition at line 88 of file qopencamwidget.cpp.{\comment endParagraph}
+}\par
+{\comment startParagraph}
+{
+References canvas, capture, and trigger.{\comment endParagraph}
+}\par
+}
+{\comment (rtfwriteRuler_thin)}
+{\pard\widctlpar\brdrb\brdrs\brdrw5\brsp20 \adjustright \par}
+{\comment startGroupHeader}
+\pard\plain \s3\sb240\sa60\keepn\widctlpar\adjustright \b\f1\cgrid
+Member Function Documentation{\comment endGroupHeader}
+\par
+\pard\plain
+{\comment startDoxyAnchor}
+{\comment startMemberDoc}
+{\xe \v paintEvent\:QOpenCamWidget}
+{\xe \v QOpenCamWidget\:paintEvent}
+\pard\plain \s4\sb240\sa60\keepn\widctlpar\adjustright \b\f1\fs20\cgrid {
+{\b
+void QOpenCamWidget::paintEvent ({\comment (startParameterList)}
+QPaintEvent * {\i event}){\comment endMemberDoc}
+}
+}{\comment (newParagraph)}
+\par
+{\comment endDoxyAnchor}
+{\bkmkstart AAAAAAAAAK}
+{\bkmkend AAAAAAAAAK}
+{\comment (startIndent) }
+{
+\pard\plain \s51\li360\sa60\sb30\qj\widctlpar\qj\adjustright \fs20\cgrid
+{\s17\sa60\sb30\widctlpar\qj \fs22\cgrid
+A paint event is a request to repaint all or part of a widget. \par
+}{\s17\sa60\sb30\widctlpar\qj \fs22\cgrid
+It can happen for one of the following reasons:\par
+{
+\par\pard\plain \s81\fi-360\li720\widctlpar\jclisttab\tx720{\*\pn \pnlvlbody\ilvl0\ls2\pnrnot0\pndec }\ls2\adjustright \fs20\cgrid
+repaint() or update() was invoked, \par\pard\plain \s81\fi-360\li720\widctlpar\jclisttab\tx720{\*\pn \pnlvlbody\ilvl0\ls2\pnrnot0\pndec }\ls2\adjustright \fs20\cgrid
+the widget was obscured and has now been uncovered, or \par\pard\plain \s81\fi-360\li720\widctlpar\jclisttab\tx720{\*\pn \pnlvlbody\ilvl0\ls2\pnrnot0\pndec }\ls2\adjustright \fs20\cgrid
+many other reasons.\par
+}
+{\b QOpenCamWidget} uses the paintEvent to draw each frame onto the screen. The paintEvent itself is regularily triggered by explicit update() calls in {\b QOpenCamWidget::grabFrame()}. \par
+}{\comment startParagraph}
+{
+Definition at line 144 of file qopencamwidget.cpp.{\comment endParagraph}
+}\par
+{\comment startParagraph}
+{
+References canvas, and nextFrame.{\comment endParagraph}
+}\par
+}
+{\comment startDoxyAnchor}
+{\comment startMemberDoc}
+{\xe \v setSnapshotVisible\:QOpenCamWidget}
+{\xe \v QOpenCamWidget\:setSnapshotVisible}
+\pard\plain \s4\sb240\sa60\keepn\widctlpar\adjustright \b\f1\fs20\cgrid {
+{\b
+void QOpenCamWidget::setSnapshotVisible ({\comment (startParameterList)}
+bool {\i visible}){\comment endMemberDoc}
+}
+}{\comment (newParagraph)}
+\par
+{\comment endDoxyAnchor}
+{\bkmkstart AAAAAAAAAL}
+{\bkmkend AAAAAAAAAL}
+{\comment (startIndent) }
+{
+\pard\plain \s51\li360\sa60\sb30\qj\widctlpar\qj\adjustright \fs20\cgrid
+{\s17\sa60\sb30\widctlpar\qj \fs22\cgrid
+Changes the visibility of the optional built-in "Take snapshot" button. \par
+}{\s17\sa60\sb30\widctlpar\qj \fs22\cgrid
+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 {\b QOpenCamWidget::startSnap} to be triggered when clicked.\par
+{{\s5\sb90\sa30\keepn\widctlpar\adjustright \b\f1\fs20\cgrid
+Parameters:\par}
+\pard\plain \s62\li720\widctlpar\ql\adjustright \fs20\cgrid {\i visible} True makes the button display, and trigger, false turns the feature off. False, i.e. no button, is default. \par
+}
+}{\comment startParagraph}
+{
+Definition at line 110 of file qopencamwidget.cpp.{\comment endParagraph}
+}\par
+{\comment startParagraph}
+{
+References layout, startSnap(), trigger, and trigger_active.{\comment endParagraph}
+}\par
+{\comment startParagraph}
+{
+Referenced by View::View().{\comment endParagraph}
+}\par
+}
+{\comment startDoxyAnchor}
+{\comment startMemberDoc}
+{\xe \v grabCapture\:QOpenCamWidget}
+{\xe \v QOpenCamWidget\:grabCapture}
+\pard\plain \s4\sb240\sa60\keepn\widctlpar\adjustright \b\f1\fs20\cgrid {
+{\b
+bool QOpenCamWidget::grabCapture ({\comment (startParameterList)}
+int {\i source}){\comment endMemberDoc}
+}
+}{\comment (newParagraph)}
+\par
+{\comment endDoxyAnchor}
+{\bkmkstart AAAAAAAAAM}
+{\bkmkend AAAAAAAAAM}
+{\comment (startIndent) }
+{
+\pard\plain \s51\li360\sa60\sb30\qj\widctlpar\qj\adjustright \fs20\cgrid
+{\s17\sa60\sb30\widctlpar\qj \fs22\cgrid
+Grabs an OpenCV video capture source. \par
+}{\s17\sa60\sb30\widctlpar\qj \fs22\cgrid
+By grabbing a source, it is meant to open the capture source, and have it ready to start streaming/capturing frames. Returns true on success, false on error. The grabCapture is separated from the constructor and/or frame-grabbing, so that you may do the error-checking you really should do before proceeding.\par
+{{\s5\sb90\sa30\keepn\widctlpar\adjustright \b\f1\fs20\cgrid
+Parameters:\par}
+\pard\plain \s62\li720\widctlpar\ql\adjustright \fs20\cgrid {\i source} The OpenCV capture source enumeration index to open \par
+}
+}{\comment startParagraph}
+{
+Definition at line 183 of file qopencamwidget.cpp.{\comment endParagraph}
+}\par
+{\comment startParagraph}
+{
+References canvas, and capture.{\comment endParagraph}
+}\par
+{\comment startParagraph}
+{
+Referenced by View::View().{\comment endParagraph}
+}\par
+}
+{\comment startDoxyAnchor}
+{\comment startMemberDoc}
+{\xe \v startCapture\:QOpenCamWidget}
+{\xe \v QOpenCamWidget\:startCapture}
+\pard\plain \s4\sb240\sa60\keepn\widctlpar\adjustright \b\f1\fs20\cgrid {
+{\b
+void QOpenCamWidget::startCapture ({\comment (startParameterList)}
+void){\comment endMemberDoc}
+}
+}{\comment (newParagraph)}
+\par
+{\comment endDoxyAnchor}
+{\bkmkstart AAAAAAAAAN}
+{\bkmkend AAAAAAAAAN}
+{\comment (startIndent) }
+{
+\pard\plain \s51\li360\sa60\sb30\qj\widctlpar\qj\adjustright \fs20\cgrid
+{\s17\sa60\sb30\widctlpar\qj \fs22\cgrid
+Starts up grabbing of video frames. \par
+}{\s17\sa60\sb30\widctlpar\qj \fs22\cgrid
+The actual grabbing and displaying of video frames is performed by a QTimer triggering the SLOT {\b QOpenCamWidget::grabFrame()}. {\b startCapture()} sets up the timer running this captureFrame loop.\par
+The SLOT {\b QOpenCamWidget::startSnap()} is used to get image frames out from the widget for other uses, like saving or processing. This function relies on the timer created and configured by {\b startCapture()}, and as such, this function is the only permitted way to start the actual capture/streaming of video from the source. \par
+}{\comment startParagraph}
+{
+Definition at line 217 of file qopencamwidget.cpp.{\comment endParagraph}
+}\par
+{\comment startParagraph}
+{
+References frametimer, grabFrame(), and trigger.{\comment endParagraph}
+}\par
+{\comment startParagraph}
+{
+Referenced by View::View().{\comment endParagraph}
+}\par
+}
+{\comment startDoxyAnchor}
+{\comment startMemberDoc}
+{\xe \v Ipl2QImage\:QOpenCamWidget}
+{\xe \v QOpenCamWidget\:Ipl2QImage}
+\pard\plain \s4\sb240\sa60\keepn\widctlpar\adjustright \b\f1\fs20\cgrid {
+{\b
+QImage * QOpenCamWidget::Ipl2QImage ({\comment (startParameterList)}
+const IplImage * {\i img}){\comment endMemberDoc}
+}
+}{\comment (newParagraph)}
+\par
+{\comment endDoxyAnchor}
+{\bkmkstart AAAAAAAAAO}
+{\bkmkend AAAAAAAAAO}
+{\comment (startIndent) }
+{
+\pard\plain \s51\li360\sa60\sb30\qj\widctlpar\qj\adjustright \fs20\cgrid
+{\s17\sa60\sb30\widctlpar\qj \fs22\cgrid
+Converts from the OpenCV IplImage data structure to a QImage. \par
+}{\s17\sa60\sb30\widctlpar\qj \fs22\cgrid
+OpenCV uses a data strcuture calles IplImage, optimized for computer vision image processing tasks. This code was adapted from kcamwidget.cpp, part of the KDE SVN at playground/multimedia/kcam/kcamwidget.cpp\par
+In regard that the IplImage can be forced into a format that aligns well with a RBG888-format, the conversion becomes one of the shortes, simples IplImage->QImage I've seen.\par
+{{\s5\sb90\sa30\keepn\widctlpar\adjustright \b\f1\fs20\cgrid
+Parameters:\par}
+\pard\plain \s62\li720\widctlpar\ql\adjustright \fs20\cgrid {\i *img} The IplImage to be converted to a QImage. \par
+}
+}{\comment startParagraph}
+{
+Definition at line 241 of file qopencamwidget.cpp.{\comment endParagraph}
+}\par
+{\comment startParagraph}
+{
+Referenced by grabFrame().{\comment endParagraph}
+}\par
+}
+{\comment startDoxyAnchor}
+{\comment startMemberDoc}
+{\xe \v grabFrame\:QOpenCamWidget}
+{\xe \v QOpenCamWidget\:grabFrame}
+\pard\plain \s4\sb240\sa60\keepn\widctlpar\adjustright \b\f1\fs20\cgrid {
+{\b
+void QOpenCamWidget::grabFrame ({\comment (startParameterList)}
+void){\f2 [slot]}{\comment endMemberDoc}
+}
+}{\comment (newParagraph)}
+\par
+{\comment endDoxyAnchor}
+{\bkmkstart AAAAAAAAAP}
+{\bkmkend AAAAAAAAAP}
+{\comment (startIndent) }
+{
+\pard\plain \s51\li360\sa60\sb30\qj\widctlpar\qj\adjustright \fs20\cgrid
+{\s17\sa60\sb30\widctlpar\qj \fs22\cgrid
+Grabs a frame and causes an update() when triggered. \par
+}{\s17\sa60\sb30\widctlpar\qj \fs22\cgrid
+This is the SLOT that actually reads the video source and causes the widget to display live video. Preferably this slot will never be called my any other signal that a timeout() on the frametimer, which is controlled by {\b QOpenCamWidget::startCapture()} \par
+}{\comment startParagraph}
+{
+Definition at line 266 of file qopencamwidget.cpp.{\comment endParagraph}
+}\par
+{\comment startParagraph}
+{
+References capture, Ipl2QImage(), and nextFrame.{\comment endParagraph}
+}\par
+{\comment startParagraph}
+{
+Referenced by startCapture().{\comment endParagraph}
+}\par
+}
+{\comment startDoxyAnchor}
+{\comment startMemberDoc}
+{\xe \v startSnap\:QOpenCamWidget}
+{\xe \v QOpenCamWidget\:startSnap}
+\pard\plain \s4\sb240\sa60\keepn\widctlpar\adjustright \b\f1\fs20\cgrid {
+{\b
+void QOpenCamWidget::startSnap ({\comment (startParameterList)}
+void){\f2 [slot]}{\comment endMemberDoc}
+}
+}{\comment (newParagraph)}
+\par
+{\comment endDoxyAnchor}
+{\bkmkstart AAAAAAAAAQ}
+{\bkmkend AAAAAAAAAQ}
+{\comment (startIndent) }
+{
+\pard\plain \s51\li360\sa60\sb30\qj\widctlpar\qj\adjustright \fs20\cgrid
+{\s17\sa60\sb30\widctlpar\qj \fs22\cgrid
+Trigger this slot to save a frame from the widget. \par
+}{\s17\sa60\sb30\widctlpar\qj \fs22\cgrid
+When this slot is triggered, the widgets capture loop is temporarily stopped, and the last displayed frame is "captured", and made available through the emitting of the class imageReady SIGNAL.\par
+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.\par
+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. \par
+}{\comment startParagraph}
+{
+Definition at line 306 of file qopencamwidget.cpp.{\comment endParagraph}
+}\par
+{\comment startParagraph}
+{
+References frametimer, imageReady(), and nextFrame.{\comment endParagraph}
+}\par
+{\comment startParagraph}
+{
+Referenced by setSnapshotVisible().{\comment endParagraph}
+}\par
+}
+{\comment startDoxyAnchor}
+{\comment startMemberDoc}
+{\xe \v imageReady\:QOpenCamWidget}
+{\xe \v QOpenCamWidget\:imageReady}
+\pard\plain \s4\sb240\sa60\keepn\widctlpar\adjustright \b\f1\fs20\cgrid {
+{\b
+void QOpenCamWidget::imageReady ({\comment (startParameterList)}
+QImage {\i snapshot}){\f2 [signal]}{\comment endMemberDoc}
+}
+}{\comment (newParagraph)}
+\par
+{\comment endDoxyAnchor}
+{\bkmkstart AAAAAAAAAR}
+{\bkmkend AAAAAAAAAR}
+{\comment (startIndent) }
+{
+\pard\plain \s51\li360\sa60\sb30\qj\widctlpar\qj\adjustright \fs20\cgrid
+{\comment startParagraph}
+{\comment (newParagraph)}
+\par
+{
+Referenced by startSnap().{\comment endParagraph}
+}\par
+}
+{\comment (rtfwriteRuler_thin)}
+{\pard\widctlpar\brdrb\brdrs\brdrw5\brsp20 \adjustright \par}
+{\comment startGroupHeader}
+\pard\plain \s3\sb240\sa60\keepn\widctlpar\adjustright \b\f1\cgrid
+Member Data Documentation{\comment endGroupHeader}
+\par
+\pard\plain
+{\comment startDoxyAnchor}
+{\comment startMemberDoc}
+{\xe \v capture\:QOpenCamWidget}
+{\xe \v QOpenCamWidget\:capture}
+\pard\plain \s4\sb240\sa60\keepn\widctlpar\adjustright \b\f1\fs20\cgrid {
+{\b
+CvCapture* {\b QOpenCamWidget::capture}{\f2 [private]}{\comment endMemberDoc}
+}
+}{\comment (newParagraph)}
+\par
+{\comment endDoxyAnchor}
+{\bkmkstart AAAAAAAAAS}
+{\bkmkend AAAAAAAAAS}
+{\comment (startIndent) }
+{
+\pard\plain \s51\li360\sa60\sb30\qj\widctlpar\qj\adjustright \fs20\cgrid
+{\comment startParagraph}
+{\comment (newParagraph)}
+\par
+{
+Definition at line 35 of file qopencamwidget.h.{\comment endParagraph}
+}\par
+{\comment startParagraph}
+{
+Referenced by grabCapture(), grabFrame(), and ~QOpenCamWidget().{\comment endParagraph}
+}\par
+}
+{\comment startDoxyAnchor}
+{\comment startMemberDoc}
+{\xe \v frametimer\:QOpenCamWidget}
+{\xe \v QOpenCamWidget\:frametimer}
+\pard\plain \s4\sb240\sa60\keepn\widctlpar\adjustright \b\f1\fs20\cgrid {
+{\b
+QTimer* {\b QOpenCamWidget::frametimer}{\f2 [private]}{\comment endMemberDoc}
+}
+}{\comment (newParagraph)}
+\par
+{\comment endDoxyAnchor}
+{\bkmkstart AAAAAAAAAT}
+{\bkmkend AAAAAAAAAT}
+{\comment (startIndent) }
+{
+\pard\plain \s51\li360\sa60\sb30\qj\widctlpar\qj\adjustright \fs20\cgrid
+{\comment startParagraph}
+{\comment (newParagraph)}
+\par
+{
+Definition at line 36 of file qopencamwidget.h.{\comment endParagraph}
+}\par
+{\comment startParagraph}
+{
+Referenced by QOpenCamWidget(), startCapture(), and startSnap().{\comment endParagraph}
+}\par
+}
+{\comment startDoxyAnchor}
+{\comment startMemberDoc}
+{\xe \v nextFrame\:QOpenCamWidget}
+{\xe \v QOpenCamWidget\:nextFrame}
+\pard\plain \s4\sb240\sa60\keepn\widctlpar\adjustright \b\f1\fs20\cgrid {
+{\b
+QImage* {\b QOpenCamWidget::nextFrame}{\f2 [private]}{\comment endMemberDoc}
+}
+}{\comment (newParagraph)}
+\par
+{\comment endDoxyAnchor}
+{\bkmkstart AAAAAAAAAU}
+{\bkmkend AAAAAAAAAU}
+{\comment (startIndent) }
+{
+\pard\plain \s51\li360\sa60\sb30\qj\widctlpar\qj\adjustright \fs20\cgrid
+{\comment startParagraph}
+{\comment (newParagraph)}
+\par
+{
+Definition at line 37 of file qopencamwidget.h.{\comment endParagraph}
+}\par
+{\comment startParagraph}
+{
+Referenced by grabFrame(), paintEvent(), QOpenCamWidget(), and startSnap().{\comment endParagraph}
+}\par
+}
+{\comment startDoxyAnchor}
+{\comment startMemberDoc}
+{\xe \v canvas\:QOpenCamWidget}
+{\xe \v QOpenCamWidget\:canvas}
+\pard\plain \s4\sb240\sa60\keepn\widctlpar\adjustright \b\f1\fs20\cgrid {
+{\b
+QLabel* {\b QOpenCamWidget::canvas}{\f2 [private]}{\comment endMemberDoc}
+}
+}{\comment (newParagraph)}
+\par
+{\comment endDoxyAnchor}
+{\bkmkstart AAAAAAAAAV}
+{\bkmkend AAAAAAAAAV}
+{\comment (startIndent) }
+{
+\pard\plain \s51\li360\sa60\sb30\qj\widctlpar\qj\adjustright \fs20\cgrid
+{\comment startParagraph}
+{\comment (newParagraph)}
+\par
+{
+Definition at line 39 of file qopencamwidget.h.{\comment endParagraph}
+}\par
+{\comment startParagraph}
+{
+Referenced by grabCapture(), paintEvent(), QOpenCamWidget(), and ~QOpenCamWidget().{\comment endParagraph}
+}\par
+}
+{\comment startDoxyAnchor}
+{\comment startMemberDoc}
+{\xe \v layout\:QOpenCamWidget}
+{\xe \v QOpenCamWidget\:layout}
+\pard\plain \s4\sb240\sa60\keepn\widctlpar\adjustright \b\f1\fs20\cgrid {
+{\b
+QVBoxLayout* {\b QOpenCamWidget::layout}{\f2 [private]}{\comment endMemberDoc}
+}
+}{\comment (newParagraph)}
+\par
+{\comment endDoxyAnchor}
+{\bkmkstart AAAAAAAAAW}
+{\bkmkend AAAAAAAAAW}
+{\comment (startIndent) }
+{
+\pard\plain \s51\li360\sa60\sb30\qj\widctlpar\qj\adjustright \fs20\cgrid
+{\comment startParagraph}
+{\comment (newParagraph)}
+\par
+{
+Definition at line 40 of file qopencamwidget.h.{\comment endParagraph}
+}\par
+{\comment startParagraph}
+{
+Referenced by QOpenCamWidget(), and setSnapshotVisible().{\comment endParagraph}
+}\par
+}
+{\comment startDoxyAnchor}
+{\comment startMemberDoc}
+{\xe \v trigger\:QOpenCamWidget}
+{\xe \v QOpenCamWidget\:trigger}
+\pard\plain \s4\sb240\sa60\keepn\widctlpar\adjustright \b\f1\fs20\cgrid {
+{\b
+QPushButton* {\b QOpenCamWidget::trigger}{\f2 [private]}{\comment endMemberDoc}
+}
+}{\comment (newParagraph)}
+\par
+{\comment endDoxyAnchor}
+{\bkmkstart AAAAAAAAAX}
+{\bkmkend AAAAAAAAAX}
+{\comment (startIndent) }
+{
+\pard\plain \s51\li360\sa60\sb30\qj\widctlpar\qj\adjustright \fs20\cgrid
+{\comment startParagraph}
+{\comment (newParagraph)}
+\par
+{
+Definition at line 41 of file qopencamwidget.h.{\comment endParagraph}
+}\par
+{\comment startParagraph}
+{
+Referenced by QOpenCamWidget(), setSnapshotVisible(), startCapture(), and ~QOpenCamWidget().{\comment endParagraph}
+}\par
+}
+{\comment startDoxyAnchor}
+{\comment startMemberDoc}
+{\xe \v trigger_active\:QOpenCamWidget}
+{\xe \v QOpenCamWidget\:trigger_active}
+\pard\plain \s4\sb240\sa60\keepn\widctlpar\adjustright \b\f1\fs20\cgrid {
+{\b
+bool {\b QOpenCamWidget::trigger_active}{\f2 [private]}{\comment endMemberDoc}
+}
+}{\comment (newParagraph)}
+\par
+{\comment endDoxyAnchor}
+{\bkmkstart AAAAAAAAAY}
+{\bkmkend AAAAAAAAAY}
+{\comment (startIndent) }
+{
+\pard\plain \s51\li360\sa60\sb30\qj\widctlpar\qj\adjustright \fs20\cgrid
+{\comment startParagraph}
+{\comment (newParagraph)}
+\par
+{
+Definition at line 42 of file qopencamwidget.h.{\comment endParagraph}
+}\par
+{\comment startParagraph}
+{
+Referenced by QOpenCamWidget(), and setSnapshotVisible().{\comment endParagraph}
+}\par
+}
+{\comment startTextBlock}
+{
+\pard\plain \s17\sa60\sb30\widctlpar\qj \fs22\cgrid {\comment (rtfwriteRuler_thin)}
+{\pard\widctlpar\brdrb\brdrs\brdrw5\brsp20 \adjustright \par}
+The documentation for this class was generated from the following files:{\comment (startItemList level=0) }
+{{\comment (writeListItem)}
+{\comment (newParagraph)}
+\par
+\pard\plain \s81\fi-360\li720\widctlpar\jclisttab\tx720{\*\pn \pnlvlbody\ilvl0\ls2\pnrnot0\pndec }\ls2\adjustright \fs20\cgrid
+{\b qopencamwidget.h}{\comment (writeListItem)}
+{\comment (newParagraph)}
+\par
+\pard\plain \s81\fi-360\li720\widctlpar\jclisttab\tx720{\*\pn \pnlvlbody\ilvl0\ls2\pnrnot0\pndec }\ls2\adjustright \fs20\cgrid
+{\b qopencamwidget.cpp}{\comment (newParagraph)}
+\par
+{\comment (endItemList level=1)}
+}{\comment endTextBlock}
+}
+{\comment endFile}
+{\comment end include classQOpenCamWidget.rtf}
+\par \pard\plain
+
+{\comment BeginRTFSection}
+\pard\plain \sect\sbkpage
+\s2\sb240\sa60\keepn\widctlpar\adjustright \b\f1\fs28\kerning28\cgrid
+{\comment begin include classView.rtf}
+{\comment startTitleHead}
+\pard\plain \s2\sb240\sa60\keepn\widctlpar\adjustright \b\f1\fs28\kerning28\cgrid
+View Class Reference{\comment endTitleHead}
+\par \pard\plain
+{\tc\tcl2 \v View}
+{\xe \v View}
+{\comment writeAnchor (classView)}
+{\bkmkstart AAAAAAAAAH}
+{\bkmkend AAAAAAAAAH}
+{\comment startTextBlock}
+{
+\pard\plain \s17\sa60\sb30\widctlpar\qj \fs22\cgrid {\f2 #include }{\comment (newParagraph)}
+\par
+{\comment (newParagraph)}
+\par
+{\comment endTextBlock}
+}
+{\comment startGroupHeader}
+\pard\plain \s3\sb240\sa60\keepn\widctlpar\adjustright \b\f1\cgrid
+Public Slots{\comment endGroupHeader}
+\par
+\pard\plain
+
+{\comment (startMemberList) }
+{
+{\comment startMemberItem }
+\pard\plain \s80\fi-360\li360\widctlpar\jclisttab\tx360{\*\pn \pnlvlbody\ilvl0\ls1\pnrnot0\pndec }\ls1\adjustright \fs20\cgrid
+void {\b saveImage} (QImage image){\comment endMemberItem }
+{\comment (newParagraph)}
+\par
+{\comment (endMemberList) }
+}
+{\comment startGroupHeader}
+\pard\plain \s3\sb240\sa60\keepn\widctlpar\adjustright \b\f1\cgrid
+Public Member Functions{\comment endGroupHeader}
+\par
+\pard\plain
+
+{\comment (startMemberList) }
+{
+{\comment startMemberItem }
+\pard\plain \s80\fi-360\li360\widctlpar\jclisttab\tx360{\*\pn \pnlvlbody\ilvl0\ls1\pnrnot0\pndec }\ls1\adjustright \fs20\cgrid
+{\b View} (QWidget *parent=0){\comment endMemberItem }
+{\comment (newParagraph)}
+\par
+{\comment startMemberItem }
+\pard\plain \s80\fi-360\li360\widctlpar\jclisttab\tx360{\*\pn \pnlvlbody\ilvl0\ls1\pnrnot0\pndec }\ls1\adjustright \fs20\cgrid
+{\b ~View} (void){\comment endMemberItem }
+{\comment (newParagraph)}
+\par
+{\comment (endMemberList) }
+}
+{\comment (rtfwriteRuler_thin)}
+{\pard\widctlpar\brdrb\brdrs\brdrw5\brsp20 \adjustright \par}
+{\comment startGroupHeader}
+\pard\plain \s3\sb240\sa60\keepn\widctlpar\adjustright \b\f1\cgrid
+Detailed Description{\comment endGroupHeader}
+\par
+\pard\plain
+{\comment startTextBlock}
+{
+\pard\plain \s17\sa60\sb30\widctlpar\qj \fs22\cgrid {\comment startParagraph}
+{
+Definition at line 5 of file view.h.{\comment endParagraph}
+}\par
+{\comment endTextBlock}
+}
+{\comment (rtfwriteRuler_thin)}
+{\pard\widctlpar\brdrb\brdrs\brdrw5\brsp20 \adjustright \par}
+{\comment startGroupHeader}
+\pard\plain \s3\sb240\sa60\keepn\widctlpar\adjustright \b\f1\cgrid
+Constructor & Destructor Documentation{\comment endGroupHeader}
+\par
+\pard\plain
+{\comment startDoxyAnchor}
+{\comment startMemberDoc}
+{\xe \v View\:View}
+{\xe \v View\:View}
+\pard\plain \s4\sb240\sa60\keepn\widctlpar\adjustright \b\f1\fs20\cgrid {
+{\b
+View::View ({\comment (startParameterList)}
+QWidget * {\i parent} = {\f2 0}){\comment endMemberDoc}
+}
+}{\comment (newParagraph)}
+\par
+{\comment endDoxyAnchor}
+{\bkmkstart AAAAAAAAAZ}
+{\bkmkend AAAAAAAAAZ}
+{\comment (startIndent) }
+{
+\pard\plain \s51\li360\sa60\sb30\qj\widctlpar\qj\adjustright \fs20\cgrid
+{\comment startParagraph}
+{\comment (newParagraph)}
+\par
+{
+Definition at line 32 of file view.cpp.{\comment endParagraph}
+}\par
+{\comment startParagraph}
+{
+References QOpenCamWidget::grabCapture(), saveImage(), QOpenCamWidget::setSnapshotVisible(), and QOpenCamWidget::startCapture().{\comment endParagraph}
+}\par
+}
+{\comment startDoxyAnchor}
+{\comment startMemberDoc}
+{\xe \v ~View\:View}
+{\xe \v View\:~View}
+\pard\plain \s4\sb240\sa60\keepn\widctlpar\adjustright \b\f1\fs20\cgrid {
+{\b
+View::~View ({\comment (startParameterList)}
+void){\comment endMemberDoc}
+}
+}{\comment (newParagraph)}
+\par
+{\comment endDoxyAnchor}
+{\bkmkstart AAAAAAAABA}
+{\bkmkend AAAAAAAABA}
+{\comment (startIndent) }
+{
+\pard\plain \s51\li360\sa60\sb30\qj\widctlpar\qj\adjustright \fs20\cgrid
+{\comment startParagraph}
+{\comment (newParagraph)}
+\par
+{
+Definition at line 74 of file view.cpp.{\comment endParagraph}
+}\par
+}
+{\comment (rtfwriteRuler_thin)}
+{\pard\widctlpar\brdrb\brdrs\brdrw5\brsp20 \adjustright \par}
+{\comment startGroupHeader}
+\pard\plain \s3\sb240\sa60\keepn\widctlpar\adjustright \b\f1\cgrid
+Member Function Documentation{\comment endGroupHeader}
+\par
+\pard\plain
+{\comment startDoxyAnchor}
+{\comment startMemberDoc}
+{\xe \v saveImage\:View}
+{\xe \v View\:saveImage}
+\pard\plain \s4\sb240\sa60\keepn\widctlpar\adjustright \b\f1\fs20\cgrid {
+{\b
+void View::saveImage ({\comment (startParameterList)}
+QImage {\i image}){\f2 [slot]}{\comment endMemberDoc}
+}
+}{\comment (newParagraph)}
+\par
+{\comment endDoxyAnchor}
+{\bkmkstart AAAAAAAABB}
+{\bkmkend AAAAAAAABB}
+{\comment (startIndent) }
+{
+\pard\plain \s51\li360\sa60\sb30\qj\widctlpar\qj\adjustright \fs20\cgrid
+{\comment startParagraph}
+{\comment (newParagraph)}
+\par
+{
+Definition at line 78 of file view.cpp.{\comment endParagraph}
+}\par
+{\comment startParagraph}
+{
+Referenced by View().{\comment endParagraph}
+}\par
+}
+{\comment startTextBlock}
+{
+\pard\plain \s17\sa60\sb30\widctlpar\qj \fs22\cgrid {\comment (rtfwriteRuler_thin)}
+{\pard\widctlpar\brdrb\brdrs\brdrw5\brsp20 \adjustright \par}
+The documentation for this class was generated from the following files:{\comment (startItemList level=0) }
+{{\comment (writeListItem)}
+{\comment (newParagraph)}
+\par
+\pard\plain \s81\fi-360\li720\widctlpar\jclisttab\tx720{\*\pn \pnlvlbody\ilvl0\ls2\pnrnot0\pndec }\ls2\adjustright \fs20\cgrid
+{\b view.h}{\comment (writeListItem)}
+{\comment (newParagraph)}
+\par
+\pard\plain \s81\fi-360\li720\widctlpar\jclisttab\tx720{\*\pn \pnlvlbody\ilvl0\ls2\pnrnot0\pndec }\ls2\adjustright \fs20\cgrid
+{\b view.cpp}{\comment (newParagraph)}
+\par
+{\comment (endItemList level=1)}
+}{\comment endTextBlock}
+}
+{\comment endFile}
+{\comment end include classView.rtf}
+
+{\comment BeginRTFChapter}
+\pard\plain \sect\sbkpage
+\s1\sb240\sa60\keepn\widctlpar\adjustright \b\f1\fs36\kerning36\cgrid
+File Documentation{\tc \v File Documentation}
+\par \pard\plain
+{\comment begin include main_8cpp.rtf}
+{\comment startTitleHead}
+\pard\plain \s2\sb240\sa60\keepn\widctlpar\adjustright \b\f1\fs28\kerning28\cgrid
+main.cpp File Reference{\comment endTitleHead}
+\par \pard\plain
+{\tc\tcl2 \v main.cpp}
+{\xe \v main.cpp}
+{\comment writeAnchor (main_8cpp)}
+{\bkmkstart AAAAAAAAAA}
+{\bkmkend AAAAAAAAAA}
+{\comment startTextBlock}
+{
+\pard\plain \s18\widctlpar\fs22\cgrid {\f2 #include }{\comment (lineBreak)}
+\par
+{\f2 #include "view.h"}{\comment (lineBreak)}
+\par
+{\comment endTextBlock}
+}
+{\comment startGroupHeader}
+\pard\plain \s3\sb240\sa60\keepn\widctlpar\adjustright \b\f1\cgrid
+Functions{\comment endGroupHeader}
+\par
+\pard\plain
+
+{\comment (startMemberList) }
+{
+{\comment startMemberItem }
+\pard\plain \s80\fi-360\li360\widctlpar\jclisttab\tx360{\*\pn \pnlvlbody\ilvl0\ls1\pnrnot0\pndec }\ls1\adjustright \fs20\cgrid
+int {\b main} (int argc, char *argv[]){\comment endMemberItem }
+{\comment (newParagraph)}
+\par
+{\comment (endMemberList) }
+}
+{\comment (rtfwriteRuler_thin)}
+{\pard\widctlpar\brdrb\brdrs\brdrw5\brsp20 \adjustright \par}
+{\comment startGroupHeader}
+\pard\plain \s3\sb240\sa60\keepn\widctlpar\adjustright \b\f1\cgrid
+Function Documentation{\comment endGroupHeader}
+\par
+\pard\plain
+{\comment startDoxyAnchor}
+{\comment startMemberDoc}
+{\xe \v main\:main.cpp}
+{\xe \v main.cpp\:main}
+\pard\plain \s4\sb240\sa60\keepn\widctlpar\adjustright \b\f1\fs20\cgrid {
+{\b
+int main ({\comment (startParameterList)}
+int {\i argc}, {\comment (startParameterList)}
+ char * {\i argv}[]){\comment endMemberDoc}
+}
+}{\comment (newParagraph)}
+\par
+{\comment endDoxyAnchor}
+{\bkmkstart AAAAAAAAAB}
+{\bkmkend AAAAAAAAAB}
+{\comment (startIndent) }
+{
+\pard\plain \s51\li360\sa60\sb30\qj\widctlpar\qj\adjustright \fs20\cgrid
+{\comment startParagraph}
+{\comment (newParagraph)}
+\par
+{
+Definition at line 28 of file main.cpp.{\comment endParagraph}
+}\par
+}
+{\comment endFile}
+{\comment end include main_8cpp.rtf}
+\par \pard\plain
+
+{\comment BeginRTFSection}
+\pard\plain \sect\sbkpage
+\s2\sb240\sa60\keepn\widctlpar\adjustright \b\f1\fs28\kerning28\cgrid
+{\comment begin include qopencamwidget_8cpp.rtf}
+{\comment startTitleHead}
+\pard\plain \s2\sb240\sa60\keepn\widctlpar\adjustright \b\f1\fs28\kerning28\cgrid
+qopencamwidget.cpp File Reference{\comment endTitleHead}
+\par \pard\plain
+{\tc\tcl2 \v qopencamwidget.cpp}
+{\xe \v qopencamwidget.cpp}
+{\comment writeAnchor (qopencamwidget_8cpp)}
+{\bkmkstart AAAAAAAAAC}
+{\bkmkend AAAAAAAAAC}
+{\comment startTextBlock}
+{
+\pard\plain \s18\widctlpar\fs22\cgrid {\f2 #include "qopencamwidget.h"}{\comment (lineBreak)}
+\par
+{\comment endTextBlock}
+}
+{\comment endFile}
+{\comment end include qopencamwidget_8cpp.rtf}
+\par \pard\plain
+
+{\comment BeginRTFSection}
+\pard\plain \sect\sbkpage
+\s2\sb240\sa60\keepn\widctlpar\adjustright \b\f1\fs28\kerning28\cgrid
+{\comment begin include qopencamwidget_8h.rtf}
+{\comment startTitleHead}
+\pard\plain \s2\sb240\sa60\keepn\widctlpar\adjustright \b\f1\fs28\kerning28\cgrid
+qopencamwidget.h File Reference{\comment endTitleHead}
+\par \pard\plain
+{\tc\tcl2 \v qopencamwidget.h}
+{\xe \v qopencamwidget.h}
+{\comment writeAnchor (qopencamwidget_8h)}
+{\bkmkstart AAAAAAAAAD}
+{\bkmkend AAAAAAAAAD}
+{\comment startTextBlock}
+{
+\pard\plain \s18\widctlpar\fs22\cgrid {\f2 #include }{\comment (lineBreak)}
+\par
+{\f2 #include }{\comment (lineBreak)}
+\par
+{\f2 #include }{\comment (lineBreak)}
+\par
+{\comment endTextBlock}
+}
+{\comment startGroupHeader}
+\pard\plain \s3\sb240\sa60\keepn\widctlpar\adjustright \b\f1\cgrid
+Classes{\comment endGroupHeader}
+\par
+\pard\plain
+
+{\comment (startMemberList) }
+{
+{\comment startMemberItem }
+\pard\plain \s80\fi-360\li360\widctlpar\jclisttab\tx360{\*\pn \pnlvlbody\ilvl0\ls1\pnrnot0\pndec }\ls1\adjustright \fs20\cgrid
+class {\b QOpenCamWidget}{\comment endMemberItem }
+{\comment (newParagraph)}
+\par
+{\comment (endMemberList) }
+}
+{\comment endFile}
+{\comment end include qopencamwidget_8h.rtf}
+\par \pard\plain
+
+{\comment BeginRTFSection}
+\pard\plain \sect\sbkpage
+\s2\sb240\sa60\keepn\widctlpar\adjustright \b\f1\fs28\kerning28\cgrid
+{\comment begin include view_8cpp.rtf}
+{\comment startTitleHead}
+\pard\plain \s2\sb240\sa60\keepn\widctlpar\adjustright \b\f1\fs28\kerning28\cgrid
+view.cpp File Reference{\comment endTitleHead}
+\par \pard\plain
+{\tc\tcl2 \v view.cpp}
+{\xe \v view.cpp}
+{\comment writeAnchor (view_8cpp)}
+{\bkmkstart AAAAAAAAAE}
+{\bkmkend AAAAAAAAAE}
+{\comment startTextBlock}
+{
+\pard\plain \s18\widctlpar\fs22\cgrid {\f2 #include "view.h"}{\comment (lineBreak)}
+\par
+{\f2 #include "qopencamwidget.h"}{\comment (lineBreak)}
+\par
+{\comment endTextBlock}
+}
+{\comment endFile}
+{\comment end include view_8cpp.rtf}
+\par \pard\plain
+
+{\comment BeginRTFSection}
+\pard\plain \sect\sbkpage
+\s2\sb240\sa60\keepn\widctlpar\adjustright \b\f1\fs28\kerning28\cgrid
+{\comment begin include view_8h.rtf}
+{\comment startTitleHead}
+\pard\plain \s2\sb240\sa60\keepn\widctlpar\adjustright \b\f1\fs28\kerning28\cgrid
+view.h File Reference{\comment endTitleHead}
+\par \pard\plain
+{\tc\tcl2 \v view.h}
+{\xe \v view.h}
+{\comment writeAnchor (view_8h)}
+{\bkmkstart AAAAAAAAAF}
+{\bkmkend AAAAAAAAAF}
+{\comment startTextBlock}
+{
+\pard\plain \s18\widctlpar\fs22\cgrid {\f2 #include }{\comment (lineBreak)}
+\par
+{\comment endTextBlock}
+}
+{\comment startGroupHeader}
+\pard\plain \s3\sb240\sa60\keepn\widctlpar\adjustright \b\f1\cgrid
+Classes{\comment endGroupHeader}
+\par
+\pard\plain
+
+{\comment (startMemberList) }
+{
+{\comment startMemberItem }
+\pard\plain \s80\fi-360\li360\widctlpar\jclisttab\tx360{\*\pn \pnlvlbody\ilvl0\ls1\pnrnot0\pndec }\ls1\adjustright \fs20\cgrid
+class {\b View}{\comment endMemberItem }
+{\comment (newParagraph)}
+\par
+{\comment (endMemberList) }
+}
+{\comment endFile}
+{\comment end include view_8h.rtf}
+
+{\comment BeginRTFChapter}
+\pard\plain \sect\sbkpage
+\s1\sb240\sa60\keepn\widctlpar\adjustright \b\f1\fs36\kerning36\cgrid
+\s1\sb240\sa60\keepn\widctlpar\adjustright \b\f1\fs36\kerning36\cgrid Index\par
+\pard\plain
+{\tc \v Index}
+{\field\fldedit {\*\fldinst INDEX \\c2 \\*MERGEFORMAT}{\fldrslt INDEX}}
+{\comment endFile}
+}
\ No newline at end of file
diff --git a/main.cpp b/main.cpp
new file mode 100644
index 0000000..787a7eb
--- /dev/null
+++ b/main.cpp
@@ -0,0 +1,36 @@
+/*
+ QOpenCamWidget demo application main code stup (main.c)
+ This file is part of a demonstration application, illustrating
+ how to use the QOpenCamWidget, a Qt 4 widget that displays
+ video input from a webcam, along with a snapshot button.
+
+ Copyright (C) 2009 Jon Langseth
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation in its version 2
+ of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include
+#include "view.h"
+
+// The contents of this file is simply a Qt Main app stub.
+int main (int argc, char*argv[])
+{
+ QApplication app(argc, argv);
+ app.setApplicationName("QOpenCamWidget testapp");
+ View v;
+ v.show();
+ return app.exec();
+}
+
diff --git a/notes b/notes
new file mode 100644
index 0000000..b93ff9c
--- /dev/null
+++ b/notes
@@ -0,0 +1,7 @@
+/*
+ * http://dridk.blogspot.com/2009/05/webcam-for-kde-new-way-for-gluon-games.html
+ * http://websvn.kde.org/trunk/playground/multimedia/kcam/kcamwidget.cpp?view=markup&pathrev=971995
+
+ * http://websvn.kde.org/trunk/playground/multimedia/kcam/kcamwidget.h?view=markup
+ * http://websvn.kde.org/trunk/playground/multimedia/kcam/kcam.cpp?view=markup
+ */
diff --git a/qcv.pro b/qcv.pro
new file mode 100644
index 0000000..3ad259c
--- /dev/null
+++ b/qcv.pro
@@ -0,0 +1,9 @@
+TEMPLATE = app
+TARGET = qcv
+DEPENDPATH += .
+LIBS += -lcv -lhighgui
+
+SOURCES += main.cpp qopencamwidget.cpp view.cpp
+HEADERS += qopencamwidget.h view.h
+
+
diff --git a/qopencamwidget.cpp b/qopencamwidget.cpp
new file mode 100644
index 0000000..cd5d1b2
--- /dev/null
+++ b/qopencamwidget.cpp
@@ -0,0 +1,319 @@
+/*
+ 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.
+
+ Copyright (C) 2009 Jon Langseth
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation in its version 2
+ of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "qopencamwidget.h"
+
+// ------------------------------------------------------------- //
+// Constructor and Destructor
+// ------------------------------------------------------------- //
+
+/*!
+ * \brief Consctructs a QWidget based widget for displaying video
+ * coming from an OpenCV capture source
+ *
+ * Including webcam data in a Qt application can be problematic,
+ * at least as long as Phonon does not support webcams, and the
+ * Phonon GStreamer backend only supports simple pipelines.
+ *
+ * This class solves the complexity of adding a webcam view,
+ * by using the cross-platform available OpenCV library.
+ *
+ * Limitations, i.e. reasons to read this code and reimplement,
+ * are: saving or streaming video is not really available (unless
+ * you do repeated timer-triggered connections to the startSnap slot),
+ * the widget size is identical to the video source dimensions (it
+ * resizes the wodget using setMinimuSize to the video dimensions,
+ * and does not handle resizing to sizes above this dimension.
+ *
+ * A brief summary of how to use this class:
+ * \code
+ * QOpenCamWidget *cw = new QOpenCamWidget(this);
+ * if ( cw->grabCapture(-1) ) {
+ * cw->setSnapshotVisible(true);
+ * cw->startCapture();
+ * }
+ * connect( cw, SIGNAL(imageReady(QImage)), this, SLOT(saveImage(QImage)));
+ * \endcode
+ *
+ * \param *parent The parent widget containing this widget, defaults to NULL.
+ *
+ **/
+QOpenCamWidget::QOpenCamWidget(QWidget *parent)
+ : QWidget(parent)
+{
+ // private CvCapture *nextFrame 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.
+ *
+ * It can happen for one of the following reasons:
+ *
+ * \li repaint() or update() was invoked,
+ * \li the widget was obscured and has now been uncovered, or
+ * \li many other reasons.
+ *
+ * QOpenCamWidget uses the paintEvent to draw each frame onto the screen.
+ * The paintEvent itself is regularily triggered by explicit update()
+ * calls in QOpenCamWidget::grabFrame().
+ *
+ **/
+void
+QOpenCamWidget::paintEvent ( QPaintEvent * event )
+{
+ QPainter * paint = new QPainter;
+ paint->begin(this);
+
+ 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) );
+ }
+ else
+ {
+ canvas->setText("No data, check/test camera");
+ }
+ paint->end();
+}
+
+
+/*!
+ * \brief Grabs an OpenCV video capture source
+ *
+ * By grabbing a source, it is meant to open the capture source,
+ * and have it ready to start streaming/capturing frames.
+ * Returns true on success, false on error. The grabCapture
+ * is separated from the constructor and/or frame-grabbing, so that you
+ * may do the error-checking you really should do before proceeding.
+ *
+ * \param source The OpenCV capture source enumeration index to open
+ *
+ **/
+bool
+QOpenCamWidget::grabCapture(int source)
+{
+ capture = cvCaptureFromCAM(0);
+ if (!capture)
+ {
+ qDebug() << "QOpenCamWidget::grabCapture(" << source << ") failed";
+ return false;
+ }
+ cvGrabFrame(capture); // Grab a single frame, do resizing based on it.
+ 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);
+
+ return true;
+}
+
+/*!
+ * \brief Starts up grabbing of video frames
+ *
+ * The actual grabbing and displaying of video frames is performed by
+ * a QTimer triggering the SLOT QOpenCamWidget::grabFrame().
+ * startCapture() sets up the timer running this captureFrame loop.
+ *
+ * The SLOT QOpenCamWidget::startSnap() is used to get image frames
+ * out from the widget for other uses, like saving or processing.
+ * This function relies on the timer created and configured by
+ * startCapture(), and as such, this function is the only permitted
+ * way to start the actual capture/streaming of video from the source.
+ *
+ **/
+void
+QOpenCamWidget::startCapture(void)
+{
+ frametimer = new QTimer(this);
+ frametimer->start(70);
+ connect(frametimer,SIGNAL(timeout()), this,SLOT(grabFrame()));
+ trigger->setEnabled(true);
+}
+
+/*!
+ * \brief Converts from the OpenCV IplImage data structure to a QImage
+ *
+ * OpenCV uses a data strcuture calles IplImage, optimized for
+ * computer vision image processing tasks. This code was adapted
+ * from kcamwidget.cpp, part of the KDE SVN at
+ * playground/multimedia/kcam/kcamwidget.cpp
+ *
+ * In regard that the IplImage can be forced into a format
+ * that aligns well with a RBG888-format, the conversion
+ * becomes one of the shortes, simples IplImage->QImage I've seen.
+ *
+ * \param *img The IplImage to be converted to a QImage.
+ *
+ **/
+QImage*
+QOpenCamWidget::Ipl2QImage(const 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);
+ return qimage;
+
+}
+// ------------------------------------------------------------- //
+// Public SLOTS
+// ------------------------------------------------------------- //
+
+/*!
+ * \brief Grabs a frame and causes an update() when triggered.
+ *
+ * This is the SLOT that actually reads the video source and
+ * causes the widget to display live video. Preferably this
+ * slot will never be called my any other signal that a timeout()
+ * on the frametimer, which is controlled by QOpenCamWidget::startCapture()
+ *
+ **/
+void QOpenCamWidget::grabFrame(void)
+{
+ if ( !capture )
+ {
+ qDebug() << "Capture device not ready!";
+ return;
+ }
+
+ cvGrabFrame(capture);
+
+ IplImage *iplimage = cvRetrieveFrame(capture);
+
+ if (iplimage)
+ {
+ nextFrame = Ipl2QImage(iplimage);
+ }
+ else
+ {
+ nextFrame = NULL;
+ }
+ update();
+}
+
+/*!
+ * \brief Trigger this slot to save a frame from the widget.
+ *
+ * When this slot is triggered, the widgets capture loop is temporarily
+ * 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.
+ *
+ **/
+void QOpenCamWidget::startSnap(void)
+{
+ if ( frametimer ) {
+ if (frametimer->isActive())
+ {
+ frametimer->stop();
+ qDebug() << "SNAP!";
+
+ emit imageReady(QImage(*nextFrame));
+ frametimer->start();
+ }
+ }
+}
+
diff --git a/qopencamwidget.h b/qopencamwidget.h
new file mode 100644
index 0000000..ef93a15
--- /dev/null
+++ b/qopencamwidget.h
@@ -0,0 +1,66 @@
+/*
+ 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.
+
+ Copyright (C) 2009 Jon Langseth
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation in its version 2
+ of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef QOPENCVWIDGET_H
+#define QOPENCVWIDGET_H
+#include
+#include
+#include
+
+class QOpenCamWidget
+ : public QWidget
+{
+ Q_OBJECT
+
+ private:
+ CvCapture *capture;
+ QTimer *frametimer;
+ QImage *nextFrame;
+ //QImage *snapshot;
+ QLabel *canvas;
+ QVBoxLayout *layout;
+ QPushButton *trigger;
+ bool trigger_active;
+
+ public:
+ // Defaults, standard elements ;)
+ QOpenCamWidget(QWidget *parent = 0);
+ ~QOpenCamWidget(void);
+
+ // Overides, reimplementation of abstract
+ 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);
+
+ public slots:
+ void grabFrame(void);
+ void startSnap();
+ signals:
+ void imageReady(QImage snapshot);
+};
+
+#endif
+
diff --git a/view.cpp b/view.cpp
new file mode 100644
index 0000000..72bc101
--- /dev/null
+++ b/view.cpp
@@ -0,0 +1,87 @@
+/*
+ QOpenCamWidget demo application main window (view.c)
+ This file is part of a demonstration application, illustrating
+ how to use the QOpenCamWidget, a Qt 4 widget that displays
+ video input from a webcam, along with a snapshot button.
+
+ Copyright (C) 2009 Jon Langseth
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation in its version 2
+ of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "view.h"
+#include "qopencamwidget.h"
+
+// The View class is a QMainWindow, used to display our QOpenCamWidget
+// The constructor of the View takes care of setting up the Widget,
+// and handles the result of a user clicking (or activating) the widget's
+// "Take snapshot" button.
+
+View::View( QWidget *parent)
+ : QMainWindow(parent)
+{
+
+ // Create the widget, setting the Main window (this) as its parent.
+ QOpenCamWidget *cw = new QOpenCamWidget(this);
+
+ // bool QOpenCamWidget::grabCapture(int source) tries to get a
+ // video capture handle from OpenCV, using the source number
+ // as the device to open. Here I use -1 as the number, meaning
+ // "give me any supported and available video devica you can find".
+ if ( cw->grabCapture(-1) )
+ {
+ // grabCapture() returns true on success. This means that
+ // we have a capture device available, and can start streaming
+ // video from the device to display on the widget.
+
+ // TODO: Document this feature..
+ cw->setSnapshotVisible(true);
+
+ // Video output does not start until QOpenCamWidget::startCapture()
+ // is explicitly called.
+ cw->startCapture();
+ }
+
+ // The QOpenCamWidget does not provide a video stream for further
+ // processing, but it does provide a snapshot of the stream if
+ // the SLOT void QOpenCamWidget::startSnap(void) is triggered.
+ // In this demo app, the slot is connected to the widgets
+ // internal "Take snapshot" trigger button, but the SLOT is
+ // public, and may easily be triggered from "outside".
+ //
+ // When startSnap() is triggered, it will use a SIGNAL to return
+ // its image, if the aquisition was successful. The image
+ // will be available through QOpenCamWidget::imageReady(Qimage);
+ // In this sample, I hook that signal up to a slot on this QMainWindow,
+ // that saves the image, and exits the application.
+ connect( cw, SIGNAL(imageReady(QImage)), this, SLOT(saveImage(QImage)));
+
+ this->setCentralWidget(cw);
+}
+
+View::~View(void)
+{
+}
+
+void View::saveImage(QImage image)
+{
+ // This is the SLOT that recieves QOpenCamWidget::imageReady(QImage) SIGNAL.
+ // To keep the example as simple as possible, I do as little as possible..
+ qDebug() << "Recieved an image of size "
+ << image.width() << "x" << image.height();
+ image.save("snapshot.png");
+
+ QApplication::exit();
+}
diff --git a/view.h b/view.h
new file mode 100644
index 0000000..6ebdb76
--- /dev/null
+++ b/view.h
@@ -0,0 +1,18 @@
+#ifndef VIEW_H
+#define VIEW_H
+#include
+
+class View
+ : public QMainWindow
+{
+ Q_OBJECT
+
+ public:
+ View(QWidget *parent = 0);
+ ~View(void);
+
+ public slots:
+ void saveImage(QImage image);
+};
+
+#endif
--
2.39.2