You are on page 1of 70

Leow Wee Kheng

CS3249 User Interface Development


Department of Computer Science, SoC, NUS

Images and Video Capture

CS3249 (SoC, NUS) Images and Video Capture 1


CS3249
CS3249 (SoC, NUS) (SoC, NUS) Images and Video Capture 1
A picture speaks a thousand words...

CS3249 (SoC, NUS) Images and Video Capture 2


CS3249 (SoC, NUS) Images and Video Capture 2
Qt Images
 Qt provides 4 classes for handling images
 QImage
 Optimised for I/O, direct pixel access and manipulation.

 QPixmap
 Optimised for display on screen.

 QBitmap
 Inherited from QPixmap for black/white images.

 QPicture
 Paint device that records and replays QPainter commands.

CS3249 (SoC, NUS) Images and Video Capture 3


CS3249 (SoC, NUS) Images and Video Capture 3
 QLabel provides an easy way to display an image.

#include <QApplication>
#include <QPixmap>
#include <QLabel>

int main(int argv, char **args)


{
QApplication app(argv, args);
QPixmap pic("butterfly.jpg"); // read image
QLabel label;
label.setPixmap(pic); // put image in label
label.show();
return app.exec();
}

CS3249 (SoC, NUS) Images and Video Capture 4


CS3249
CS3249 (SoC, NUS) (SoC, NUS) Images and Video Capture 4
QLabel with an image

CS3249 (SoC, NUS) Images and Video Capture 5


CS3249
CS3249 (SoC, NUS) (SoC, NUS) Images and Video Capture 5
Painting QWidget
 For finer control, directly paint QWidget.
 Create ImageWidget as subclass of QWidget.
 Allow user to zoom image with mouse wheel.
 Need to override two event handlers:
 paintEvent: paints in the widget.

 wheelEvent: processes mouse wheel input.

 Programming ImageWidget is rather tricky.


Need to write specification to make requirements clear.

CS3249 (SoC, NUS) Images and Video Capture 6


CS3249 (SoC, NUS) Images and Video Capture 6
Specification of ImageWidget
 ImageWidget size
 Initial size
 Default depends on platform and screen geometry.

 Set to (800, 600), width = 800, height = 600.

 Minimum size is given by minimumSize().


 Default is (0, 0), which causes widget to disappear.

 Choose (10, 10).

 Client class can change it by calling setMinimumSize().

 Maximum size is given by maximumSize().


 Default is (16777215, 16777215).

 Keep this default.

 Client class can change it by calling setMaximumSize().

CS3249 (SoC, NUS) Images and Video Capture 7


CS3249 (SoC, NUS) Images and Video Capture 7
 Displayed image size
 Displayed image size = zoom  input image size, subject to
minimumSize() ≤ displayed image size ≤ maximumSize()
 ImageWidget size always equals displayed image size.

 setImage(fileName)
 Loads image with file name fileName.
 Initial zoom should be as large as possible but ≤ 1.0
such that displayed image size ≤ initial widget size.
 For image ≤ initial widget size, initial zoom = 1.0.

 For image > initial widget size, initial zoom < 1.0.

CS3249 (SoC, NUS) Images and Video Capture 8


CS3249
CS3249 (SoC, NUS) (SoC, NUS) Images and Video Capture 8
 Zooming
 Zoom factor > 0.
 Client class can call setZoom(newZoom) to zoom.
 User can zoom in or out using mouse wheel.
 Each mouse wheel step increases or decreases zoom by0.1.

CS3249 (SoC, NUS) Images and Video Capture 9


CS3249
CS3249 (SoC, NUS) (SoC, NUS) Images and Video Capture 9
// ImageWidget.h

#ifndef IMAGEWIDGET_H
#define IMAGEWIDGET_H

#include <QWidget>
#include <QImage>
#include <QPixmap>

class ImageWidget: public QWidget


{
Q_OBJECT
Q_PROPERTY(float zoom READ getZoom WRITE setZoom)

CS3249 (SoC, NUS) Images and Video Capture 10


CS3249
CS3249 (SoC, NUS) (SoC, NUS) Images and Video Capture 10
 Property
 Like class variable but has addition features:

Q_PROPERTY(type name
READ getFunction
[WRITE setFunction]
[RESET resetFunction]
[NOTIFY notifySignal]
...
)

 type can be any type supported by QVariant.


 READ declares accessor function.
 WRITE, RESET declare modifier functions (optional).
 NOTIFY declares a signal to be emitted (optional).
 Qt's property system is platform-independent.

CS3249 (SoC, NUS) Images and Video Capture 11


CS3249
CS3249 (SoC, NUS) (SoC, NUS) Images and Video Capture 11
public:
ImageWidget(QWidget *parent = 0);
void setImage(const QString &fileName);

float getZoom() const { return zoom; } // inline


void setZoom(float newZoom);

protected:
void paintEvent(QPaintEvent *event);
void wheelEvent(QWheelEvent *event);

private:
QPixmap input; // Input image.
QPixmap display; // Displayed image.
float zoom;
};

#endif

CS3249 (SoC, NUS) Images and Video Capture 12


CS3249
CS3249 (SoC, NUS) (SoC, NUS) Images and Video Capture 12
// ImageWidget.cpp

#include <QtGui>
#include "ImageWidget.h"

ImageWidget::ImageWidget(QWidget *parent): QWidget(parent)


{
// Set defaults
zoom = 0.0;
setMinimumSize(10, 10); // width, height
}

CS3249 (SoC, NUS) Images and Video Capture 13


CS3249
CS3249 (SoC, NUS) (SoC, NUS) Images and Video Capture 13
void ImageWidget::setImage(const QString &fileName)
{
QImage image = QImage(fileName); // Get image
input = QPixmap::fromImage(image); // For display

// Determine appropriate initial zoom


float initWidth = 800;
float initHeight = 600;
float wRatio = (float) initWidth /
(float) input.width();
float hRatio = (float) initHeight /
(float) input.height();
float initZoom = qMin(wRatio, hRatio);

if (initZoom >= 1.0)


initZoom = 1.0; // Use original size if possible.

setZoom(initZoom);
}

CS3249 (SoC, NUS) Images and Video Capture 14


CS3249
CS3249 (SoC, NUS) (SoC, NUS) Images and Video Capture 14
void ImageWidget::setZoom(float newZoom)
{
if (newZoom <= 0.0)
return; // no change

QSize newSize = newZoom * input.size();


if (newSize.width() < minimumWidth() ||
newSize.height() < minimumHeight() ||
newSize.width() > maximumWidth() ||
newSize.height() > maximumHeight())
return; // no change

zoom = newZoom;
display = input.scaled(zoom * input.size(),
Qt::KeepAspectRatio);
qDebug("zoom %f", zoom); // for debugging
resize(display.size());
}

CS3249 (SoC, NUS) Images and Video Capture 15


CS3249
CS3249 (SoC, NUS) (SoC, NUS) Images and Video Capture 15
 input.scaled(...)
 Scales input to zoom * input.size().
 Always scales from input to get optimal image resolution.
Don't rescale the scaled displayed image.
 resize()
 Resizes widget, then sends QResizeEvent to widget.
 Widget's resizeEvent() is called.
 resizeEvent()
 Widget already has new size.
 At the end of the function, sends QPaintEvent to widget.
 Widget's paintEvent() is called.
 Window system may send additional resize events.

CS3249 (SoC, NUS) Images and Video Capture 16


CS3249
CS3249 (SoC, NUS) (SoC, NUS) Images and Video Capture 16
// Event handlers

void ImageWidget::paintEvent(QPaintEvent *event)


{
QRectF rect = QRectF(QPoint(), size());
QPainter painter(this);
painter.drawPixmap(rect, display, rect);
}

 QRectF(top-left, size) defines a rectangular region.


 QPoint() returns (0, 0).
 painter(this) creates a QPainter for ImageWidget.
 drawPixmap(target, pixmap, source)
draws source part of pixmap into target part of ImageWidget.

CS3249 (SoC, NUS) Images and Video Capture 17


CS3249
CS3249 (SoC, NUS) (SoC, NUS) Images and Video Capture 17
 Caution
 Calling resize() in resizeEvent() may cause infinite
recursion.
 Calling update() or repaint() in paintEvent() will cause
infinite recursion.

CS3249 (SoC, NUS) Images and Video Capture 18


CS3249
CS3249 (SoC, NUS) (SoC, NUS) Images and Video Capture 18
void ImageWidget::wheelEvent(QWheelEvent *event)
{
float step = event->delta() / 1200.0;
float newZoom = zoom + step;

char string[100];
sprintf(string, "%.1f", newZoom);
sscanf(string, "%f", &newZoom); // rounding
setZoom(newZoom);
}

 delta() returns integer value in units of 1/8 degree.


 Most mouse wheels rotate in steps of 15 degree,
i.e., 15 / (1/8) = 120 units.
 Divide by 1200.0 to get zoom step of 0.1.

CS3249 (SoC, NUS) Images and Video Capture 19


CS3249
CS3249 (SoC, NUS) (SoC, NUS) Images and Video Capture 19
// main.cpp

#include <QApplication>
#include "ImageWidget.h"

int main(int argc, char *argv[])


{
QApplication app(argc, argv);
ImageWidget widget;
// widget.setMinimumSize(50, 50);
// widget.setMaximumSize(1100, 700);

if (argc > 1)
widget.setImage(argv[1]);
widget.show();
return app.exec();
}

CS3249 (SoC, NUS) Images and Video Capture 20


CS3249
CS3249 (SoC, NUS) (SoC, NUS) Images and Video Capture 20
 This example is incomplete:
 Doesn't display an image smaller than minimum widget size.

CS3249 (SoC, NUS) Images and Video Capture 22


CS3249
CS3249 (SoC, NUS) (SoC, NUS) Images and Video Capture 22
 This example is incomplete:
 Changing widget size has no effect on displayed image.

CS3249 (SoC, NUS) Images and Video Capture 23


CS3249
CS3249 (SoC, NUS) (SoC, NUS) Images and Video Capture 23
Image is larger than screen?
Two ways to handle large images
 Use scroll area
 Put widget in scroll area.
 Easy to implement.
 Let user pan image
 ImageWidget displays a part of image.
 User uses mouse button to pan image.
 More challenging to implement.
 See UI Challenge in Assignment 2.

CS3249 (SoC, NUS) Images and Video Capture 24


CS3249 (SoC, NUS) Images and Video Capture 24
Using Scroll Area
 QScrollArea
 Subclass of QWidget.
 Provides scrolling view onto another widget.
 Put ImageWidget in QScrollArea
 No change to ImageWidget.
 Scroll bars appear if ImageWidget is too large.

CS3249 (SoC, NUS) Images and Video Capture 25


CS3249 (SoC, NUS) Images and Video Capture 25
// main.cpp
Really easy!
#include <QApplication> There's usually
#include <QScrollArea> an easy way
#include "ImageWidget.h"
to do things in Qt!
int main(int argc, char *argv[])
{
QApplication app(argc, argv);

ImageWidget *widget = new ImageWidget;


if (argc > 1)
widget->setImage(argv[1]);

QScrollArea *scroll = new QScrollArea;


scroll->setWidget(widget);

scroll->show();
return app.exec();
}

CS3249 (SoC, NUS) Images and Video Capture 26


CS3249
CS3249 (SoC, NUS) (SoC, NUS) Images and Video Capture 26
Interfacing Devices
 Modern computers support many novel devices.

CS3249 (SoC, NUS) Images and Video Capture 29


CS3249 (SoC, NUS) Images and Video Capture 29
 3 basic ways to interface devices:
 Wait for framework developers to develop device interface.
 e.g., QCamera is available in Qt 5.

 How long can you wait?

 Integrate existing tools.


 e.g., OpenCV has camera interface.

 Relatively easy to integrate OpenCV into Qt.

 Develop device drivers.


 Require detailed knowledge.

 Very difficult.

CS3249 (SoC, NUS) Images and Video Capture 30


CS3249
CS3249 (SoC, NUS) (SoC, NUS) Images and Video Capture 30
Interface Webcam with OpenCV
 Cross-platform open source library for computer vision.
 OpenCV 1 was written in C.
 OpenCV 2 provides C, C++, Python, Java interfaces.
 Supports Linux, Windows, Mac OS, iOS, Andriod.
 Going to support Parallel Javascript.

CS3249 (SoC, NUS) Images and Video Capture 31


CS3249 (SoC, NUS) Images and Video Capture 31
 OpenCV 2 example for video capture with webcam.

// webcam.c

#include <core_c.h>
#include <highgui_c.h>

int main(int argc, char **args)


{
int dev = 0; // 0: default, > 0: other cameras.

cvNamedWindow("webcam", 1); // Create OpenCV window.

CvCapture* capture = cvCaptureFromCAM(dev);


cvSetCaptureProperty(capture,
CV_CAP_PROP_FRAME_WIDTH, 640);
cvSetCaptureProperty(capture,
CV_CAP_PROP_FRAME_HEIGHT, 480);

CS3249 (SoC, NUS) Images and Video Capture 32


CS3249
CS3249 (SoC, NUS) (SoC, NUS) Images and Video Capture 32
while(1)
{
IplImage *frame = cvQueryFrame(capture);

cvShowImage("webcam", frame);

char key = cvWaitKey(10);


if (key == 27) // If key is ESC,
break; // break out of loop.
}

cvReleaseCapture(&capture);
cvDestroyWindow("webcam");
return 0;
}

CS3249 (SoC, NUS) Images and Video Capture 33


CS3249
CS3249 (SoC, NUS) (SoC, NUS) Images and Video Capture 33
Integrating OpenCV in Qt
 OpenCV video capture program is sequential.
 Qt is event-driven.
 To integrate OpenCV in Qt:
 Use Qt timer event to generate regularly timed events.
 Call OpenCV function upon receiving timer event.
 Convert OpenCV image to QImage for display.

CS3249 (SoC, NUS) Images and Video Capture 35


CS3249 (SoC, NUS) Images and Video Capture 35
 Integrate OpenCV video capture functions in Qt.

Native Webcam
screen display (QWidget)
interface output

QTimer
init timer
OpenCV
video capture OpenCV event
get frame
functions interface
frame

CS3249 (SoC, NUS) Images and Video Capture 36


CS3249
CS3249 (SoC, NUS) (SoC, NUS) Images and Video Capture 36
// Webcam.h

#ifndef WEBCAM_H
#define WEBCAM_H

#include <QWidget>
#include <QTime>
#include <core_c.h>
#include <highgui_c.h>

class Webcam: public QWidget


{
Q_OBJECT

public:
Webcam(int dev, int fps);
~Webcam();

CS3249 (SoC, NUS) Images and Video Capture 37


CS3249
CS3249 (SoC, NUS) (SoC, NUS) Images and Video Capture 37
protected:
void showEvent(QShowEvent *event);
void hideEvent(QHideEvent *event);
void timerEvent(QTimerEvent *event);
void paintEvent(QPaintEvent *event);

private:
CvCapture* capture;
int timerId;
int frameRate; // input frame rate
QPixmap pixmap;
int nframes; // used to calculate actual frame rate
QTime time; // used to calculate actual frame rate

// convert image format


QImage IplImage2QImage(const IplImage *iplImage);
};

#endif

CS3249 (SoC, NUS) Images and Video Capture 38


CS3249
CS3249 (SoC, NUS) (SoC, NUS) Images and Video Capture 38
// Webcam.cpp

#include <QtGui>
#include "Webcam.h"

Webcam::Webcam(int dev, int fps)


{
timerId = 0;
frameRate = fps;
capture = cvCaptureFromCAM(dev);

int width = 640;


int height = 480;
cvSetCaptureProperty(capture,
CV_CAP_PROP_FRAME_WIDTH, width);
cvSetCaptureProperty(capture,
CV_CAP_PROP_FRAME_HEIGHT, height);
setFixedSize(width, height);
}

CS3249 (SoC, NUS) Images and Video Capture 39


CS3249
CS3249 (SoC, NUS) (SoC, NUS) Images and Video Capture 39
Webcam::~Webcam()
{
cvReleaseCapture(&capture);
}

void Webcam::showEvent(QShowEvent *event)


{
nframes = 0; // init
timerId = startTimer(1000 / frameRate); // in msec
time.start(); // start time
}

void Webcam::hideEvent(QHideEvent *event)


{
killTimer(timerId);
}

CS3249 (SoC, NUS) Images and Video Capture 40


CS3249
CS3249 (SoC, NUS) (SoC, NUS) Images and Video Capture 40
void Webcam::timerEvent(QTimerEvent *event)
{
if (event->timerId() == timerId)
{
IplImage *frame = cvQueryFrame(capture);
QImage image = IplImage2QImage(frame); // convert
pixmap = QPixmap::fromImage(image); // convert
repaint(); // immediate repaint

if (++nframes == 50)
{
qDebug("frame rate: %f", // actual frame rate
(float) nframes * 1000 / time.elapsed());
nframes = 0;
time.restart();
}
}
else
QWidget::timerEvent(event);
}

CS3249 (SoC, NUS) Images and Video Capture 41


CS3249
CS3249 (SoC, NUS) (SoC, NUS) Images and Video Capture 41
void Webcam::paintEvent(QPaintEvent *event)
{
QRectF rect = QRectF(QPoint(), size());
QPainter painter(this);
painter.drawPixmap(rect, pixmap, rect);
}

CS3249 (SoC, NUS) Images and Video Capture 42


CS3249
CS3249 (SoC, NUS) (SoC, NUS) Images and Video Capture 42
// Convert OpenCV's IplImage to QImage.

QImage Webcam::IplImage2QImage(const IplImage *iplImage)


{
int height = iplImage->height;
int width = iplImage->width;

if(iplImage->depth == IPL_DEPTH_8U &&


iplImage->nChannels == 3) // colour image
{
const uchar *qImageBuffer =
(const uchar*) iplImage->imageData;
QImage img(qImageBuffer, width, height,
QImage::Format_RGB888);
return img.rgbSwapped();
}

CS3249 (SoC, NUS) Images and Video Capture 43


CS3249
CS3249 (SoC, NUS) (SoC, NUS) Images and Video Capture 43
else if(iplImage->depth == IPL_DEPTH_8U &&
iplImage->nChannels == 1) // gray image
{
const uchar *qImageBuffer =
(const uchar*) iplImage->imageData;
QImage img(qImageBuffer, width, height,
QImage::Format_Indexed8);

QVector<QRgb> colorTable; // set up colour table


for (int i = 0; i < 256; i++)
colorTable.append(qRgb(i, i, i));

img.setColorTable(colorTable);
return img;
}
else
{
qWarning() << "Image cannot be converted.";
return QImage();
}
}
CS3249 (SoC, NUS) Images and Video Capture 44
CS3249
CS3249 (SoC, NUS) (SoC, NUS) Images and Video Capture 44
// main.cpp

#include <QApplication>
#include "Webcam.h"
#include "stdio.h"

int main(int argc, char **args)


{
QApplication app(argc, args);

int dev = 0; // default device


int fps = 25; // 25 frames per second
if (argc > 1)
sscanf(args[1], "%d", &dev);
if (argc > 2)
sscanf(args[2], "%d", &fps);

Webcam *view = new Webcam(dev, fps);


view->show();
return app.exec();
}
CS3249 (SoC, NUS) Images and Video Capture 45
CS3249
CS3249 (SoC, NUS) (SoC, NUS) Images and Video Capture 45
# webcam.pro
# Run qmake -project to generate file.
# Then, add the include line.
# Then, run qmake followed by make.

TEMPLATE = app
TARGET =
DEPENDPATH += .
INCLUDEPATH += .

# include additional compiler info for OpenCV


include(opencv.pro)

# Input
HEADERS += Webcam.h
SOURCES += main.cpp Webcam.cpp

CS3249 (SoC, NUS) Images and Video Capture 46


CS3249
CS3249 (SoC, NUS) (SoC, NUS) Images and Video Capture 46
# opencv.pro

QMAKE_CXXFLAGS += -Wno-deprecated
INCLUDEPATH += /usr/include/opencv2/core
/usr/include/opencv2/highgui
LIBS += -L/usr/lib -lopencv_core -lopencv_imgproc
-lopencv_highgui

CS3249 (SoC, NUS) Images and Video Capture 47


CS3249
CS3249 (SoC, NUS) (SoC, NUS) Images and Video Capture 47
 Notes on video capture
 Most cameras have a max frame rate, e.g., 30 fps.
 When desired frame rate > max frame rate,
program can only run at max frame rate.

CS3249 (SoC, NUS) Images and Video Capture 48


CS3249
CS3249 (SoC, NUS) (SoC, NUS) Images and Video Capture 48
Real-Time Video Processing

Image
Processor

Native Webcam
screen display (QWidget)
interface output processed
image

QTimer
init timer
OpenCV
video capture OpenCV event
get frame
functions interface
frame
CS3249 (SoC, NUS) Images and Video Capture 49
CS3249 (SoC, NUS) Images and Video Capture 49
// ImageProc.h

#ifndef IMAGEPROC_H
#define IMAGEPROC_H

#include <core_c.h>
#include <highgui_c.h>

class ImageProc
{
public:
IplImage *process(IplImage *source, int type);
};

#endif

CS3249 (SoC, NUS) Images and Video Capture 50


CS3249
CS3249 (SoC, NUS) (SoC, NUS) Images and Video Capture 50
// ImageProc.cpp

#include "ImageProc.h"
#include <imgproc_c.h>

IplImage *ImageProc::process(IplImage *source, int type)


{
static IplImage *target = NULL;

if (target)
cvReleaseImage(&target);

target = cvCreateImage(
cvSize(source->width, source->height),
source->depth, source->nChannels);

CS3249 (SoC, NUS) Images and Video Capture 51


CS3249
CS3249 (SoC, NUS) (SoC, NUS) Images and Video Capture 51
switch(type)
{
case 0: // do nothing
return source;

case 1: // demo fast algo: fast smoothing


cvSmooth(source, target, CV_GAUSSIAN, 5);
return target;

CS3249 (SoC, NUS) Images and Video Capture 52


CS3249
CS3249 (SoC, NUS) (SoC, NUS) Images and Video Capture 52
case 2: // demo slow algo: filter with large kernel
{
int size = 100;
CvMat *kernel = cvCreateMat(size, size,
CV_32FC1);
cvSet(kernel, cvScalar(1.0 / size / size));
cvFilter2D(source, target, kernel);
cvReleaseMat(&kernel);

// Filter target is too blurred for display.


// Display the following for demo purpose.
cvSmooth(source, target, CV_GAUSSIAN, 5);
return target;
}

default: // do nothing
return source;
}
}

CS3249 (SoC, NUS) Images and Video Capture 53


CS3249
CS3249 (SoC, NUS) (SoC, NUS) Images and Video Capture 53
// Webcam.h

class Webcam: public QWidget


{
Q_OBJECT

public:
Webcam(int dev, int fps, int type);
~Webcam();
...

protected:
...
void timerEvent(QTimerEvent *event);

private:
...
ImageProc *imageProc;
int demoType;
};

CS3249 (SoC, NUS) Images and Video Capture 54


CS3249
CS3249 (SoC, NUS) (SoC, NUS) Images and Video Capture 54
// Webcam.cpp

Webcam::Webcam(int dev, int fps, int type)


{
timerId = 0;
frameRate = fps;
demoType = type;

capture = cvCaptureFromCAM(dev);

int width = 640;


int height = 480;
cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH,
width);
cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT,
height);
setFixedSize(width, height);

imageProc = new ImageProc;


}

CS3249 (SoC, NUS) Images and Video Capture 55


CS3249
CS3249 (SoC, NUS) (SoC, NUS) Images and Video Capture 55
// Webcam.cpp

Webcam::~Webcam()
{
cvReleaseCapture(&capture);
delete imageProc;
}

CS3249 (SoC, NUS) Images and Video Capture 56


CS3249
CS3249 (SoC, NUS) (SoC, NUS) Images and Video Capture 56
void Webcam::timerEvent(QTimerEvent *event)
{
if (event->timerId() == timerId)
{
IplImage *frame = cvQueryFrame(capture);
IplImage *target =
imageProc->process(frame, demoType);
QImage image = IplImage2QImage(target);
pixmap = QPixmap::fromImage(image);
repaint();

...
}
}

CS3249 (SoC, NUS) Images and Video Capture 57


CS3249
CS3249 (SoC, NUS) (SoC, NUS) Images and Video Capture 57
Response Time
 Let desired frame rate = 25 fps.
 Frame interval τ = 1 / 25 sec = 40 msec.
 Timer event
 ck : time at which timer event arrives.
 Video capture
 fk : time at which video frame k is captured.
 Frame processing
 dk : time at which frame k is displayed after processing.

CS3249 (SoC, NUS) Images and Video Capture 58


CS3249 (SoC, NUS) Images and Video Capture 58
 Response time
 Frame capture time = fk – ck.
 Frame processing time = dk – fk .
 Response time rk = dk – ck.
 Want rk ≤ τ.

CS3249 (SoC, NUS) Images and Video Capture 59


CS3249
CS3249 (SoC, NUS) (SoC, NUS) Images and Video Capture 59
 Fast processing
 Response time r < τ
 Actual frame rate = desired frame rate.

CS3249 (SoC, NUS) Images and Video Capture 60


CS3249
CS3249 (SoC, NUS) (SoC, NUS) Images and Video Capture 60
 Slower processing
 Response time r ≈ 2τ.
 Actual frame rate ≈ 1/2 desired frame rate.
 Slower rate but still responsive.

 Question:
 Timer events can fire at desired frame rate.
What happen to missing timer events (dotted arrows)?

CS3249 (SoC, NUS) Images and Video Capture 61


CS3249
CS3249 (SoC, NUS) (SoC, NUS) Images and Video Capture 61
General Software Architecture
 Better to split input and output modules.

output

Native Webcam
screen display (QWidget)
interface output

QTimer
init timer
OpenCV
video capture OpenCV event
get frame
functions interface
frame
input
CS3249 (SoC, NUS) Images and Video Capture 63
CS3249 (SoC, NUS) Images and Video Capture 63
processed
image
Native Main
display
screen Window
output
interface
QTimer Image
Processor
generic
init camera timer
functions event
init get frame
frame

init
OpenCV Webcam
video capture get frame (camera
functions interface)
frame

CS3249 (SoC, NUS) Images and Video Capture 64


CS3249
CS3249 (SoC, NUS) (SoC, NUS) Images and Video Capture 64
processed
image
Main
display
Window
output
QTimer Image
Processor
generic
init camera timer
simplified functions event
diagram
init get frame
frame

init
OpenCV Webcam
video capture get frame (camera
functions interface)
frame

CS3249 (SoC, NUS) Images and Video Capture 65


CS3249
CS3249 (SoC, NUS) (SoC, NUS) Images and Video Capture 65
processed
image
Main
display
Window
output
Image
Processor
generic
camera
Which pattern functions
is this?
init get frame
frame

init
OpenCV Webcam
video capture get frame (camera
functions interface)
frame

CS3249 (SoC, NUS) Images and Video Capture 66


CS3249
CS3249 (SoC, NUS) (SoC, NUS) Images and Video Capture 66
Summary
 Working with images
 Use QImage for input/output.
 Use QPixmap for painting on QWidget.
 Reimplement event handlers
 paintEvent(), wheelEvent(), etc.

 Write specification to clarity requirements.


 Integrating devices
 Use existing tools with hardware interfaces.
 Integrate tools into Qt.
 Need to convert data to/from Qt format.
 Check response time.

CS3249 (SoC, NUS) Images and Video Capture 67


CS3249 (SoC, NUS) Images and Video Capture 67
Further Reading
 2D and 3D graphics: [Blan2008], Chap. 8.

CS3249 (SoC, NUS) Images and Video Capture 68


CS3249 (SoC, NUS) Images and Video Capture 68
Exercise
 Modify the sample codes into 3 loosely coupled parts:
 Main window: displays video frame and interacts with user.
 Webcam: captures video frame.
 ImageProc: processes images.

CS3249 (SoC, NUS) Images and Video Capture 69


CS3249 (SoC, NUS) Images and Video Capture 69
References
 J. Blanchette and M. Summerfield, C++ GUI Programming with
Qt 4, 2nd ed., Prentice Hall, 2008.
 OpenCV Reference Manual.

CS3249 (SoC, NUS) Images and Video Capture 70


CS3249 (SoC, NUS) Images and Video Capture 70

You might also like