-
Notifications
You must be signed in to change notification settings - Fork 3
/
VideoCapture.cpp
157 lines (135 loc) · 3.71 KB
/
VideoCapture.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
#ifdef USE_VIDEO_INPUT
#include <videoInput.h>
#else
#include <cv.h>
#include <highgui.h>
#endif
#include "VideoCapture.h"
#include <QDebug>
#include <QApplication>
struct VideoCapture::Private {
#if USE_VIDEO_INPUT
videoInput * m_cap;
#else
cv::VideoCapture * m_cap;
#endif
Private()
: m_cap(0)
{}
};
VideoCapture::VideoCapture(QThread * thread, QObject *parent)
: QObject(parent)
, m_private(new Private)
, m_openDevice(-1)
, m_resW(0)
, m_resH(0)
, m_clock(0)
{
if (!thread) thread = new QThread();
moveToThread(thread);
Q_ASSERT(connect(thread, SIGNAL(started()), SLOT(onThreadStarted())));
}
VideoCapture::~VideoCapture()
{
if (m_private->m_cap)
closeDevice();
}
void VideoCapture::onThreadStarted()
{
m_clock = new QTimer(this);
Q_ASSERT(m_clock);
Q_ASSERT(connect(m_clock, SIGNAL(timeout()), SLOT(onClockTick())));
#ifdef USE_VIDEO_INPUT
m_private->m_cap = new videoInput;
#else
m_private->m_cap = new cv::VideoCapture;
#endif
Q_ASSERT(m_private->m_cap);
scanForDevices();
}
void VideoCapture::openDevice(int index)
{
Q_ASSERT(m_private->m_cap);
if (index < 0 || index >= m_deviceCount) {
qCritical() << "Camera index out of range:" << index;
return;
}
closeDevice();
m_openDevice = index;
#ifdef USE_VIDEO_INPUT
m_private->m_cap->setIdealFramerate(m_openDevice, 25);
m_private->m_cap->setAutoReconnectOnFreeze(m_openDevice,true,7);
if (m_resW && m_resH)
m_private->m_cap->setupDevice(m_openDevice,m_resW,m_resH);
else
m_private->m_cap->setupDevice(m_openDevice);
m_resW = m_private->m_cap->getWidth(m_openDevice);
m_resH = m_private->m_cap->getHeight(m_openDevice);
#else
m_private->m_cap->set(CV_CAP_PROP_FPS, 25);
if (m_resW && m_resH) {
m_private->m_cap->set(CV_CAP_PROP_FRAME_WIDTH, m_resW);
m_private->m_cap->set(CV_CAP_PROP_FRAME_HEIGHT, m_resH);
}
if (!m_private->m_cap->open(index)) {
qCritical() << "Failed to open camera";
m_openDevice = -1;
return;
}
// properties are just hints - figure them out
m_resW = (int)m_private->m_cap->get(CV_CAP_PROP_FRAME_WIDTH);
m_resH = (int)m_private->m_cap->get(CV_CAP_PROP_FRAME_HEIGHT);
#endif
emit autoResolution( m_resW, m_resH );
m_clock->start(40);
}
void VideoCapture::onClockTick()
{
Q_ASSERT(m_private->m_cap);
QImage frame = QImage(m_resW, m_resH, QImage::Format_RGB888);
#ifdef USE_VIDEO_INPUT
if ((m_openDevice > -1) && m_private->m_cap->isFrameNew(m_openDevice)) {
m_private->m_cap->getPixels(m_openDevice, frame.bits(), true, true);
emit gotFrame(frame);
}
#else
if ((m_openDevice > -1) && m_private->m_cap->grab()) {
// wrap a cv::Mat around a frame...
cv::Mat mat;
m_private->m_cap->retrieve(mat);
emit gotFrame(frame);
}
#endif
}
void VideoCapture::scanForDevices()
{
QStringList camNames;
#ifdef USE_VIDEO_INPUT
Q_ASSERT(m_private->m_cap);
// stupid, that videoInput doesn't do that itself, but...
int nCams = m_private->m_cap->devicesFound = m_private->m_cap->listDevices();
for(int i = 0; i < nCams; ++i)
camNames << m_private->m_cap->getDeviceName(i);
#endif
emit foundDevices(camNames);
}
void VideoCapture::closeDevice()
{
#ifdef USE_VIDEO_INPUT
Q_ASSERT(m_private->m_cap);
if (m_openDevice > -1)
m_private->m_cap->stopDevice(m_openDevice);
#endif
}
void VideoCapture::setupResolution(int w, int h)
{
m_resW = w;
m_resH = h;
#ifdef USE_VIDEO_INPUT
// if camera is open...
if (m_private->m_cap && m_openDevice > -1) {
// ... reopen with new settings
openDevice(m_openDevice);
}
#endif
}