-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathKinectFacestream.cpp
executable file
·244 lines (200 loc) · 7.07 KB
/
KinectFacestream.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
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
/**
* @file KinectFaceStream.cpp
* @ingroup Kinect
* @author Dominique Vaufreydaz, Grenoble Alpes University, Inria
* @copyright All right reserved.
*/
#include "KinectFaceStream.h"
using namespace MobileRGBD::Kinect2;
KinectFaceStream::KinectFaceStream(KinectSensor& KinectSensorCaller) : KinectExtraRecorder(KinectSensorCaller)
{
for( auto i = 0; i < BODY_COUNT; i++ )
{
BodyTrackingIds[i] = 0;
StartedSearch[i] = false;
}
}
void KinectFaceStream::Exchange(KinectBodies& CurrentBodies)
{
Omiscid::SmartLocker SL_Protection(Protection);
bool FaceTrackerActuallySet[BODY_COUNT] = { false };
unsigned int iBody;
for( iBody = 0; iBody < CurrentBodies.ActualNbBody; iBody++ )
{
// Get original index to let the frame tracker to ba associated with the same index
int BodyOriginalIndex = CurrentBodies.InitialBodyIndex[iBody];
// Ok, we have a body tracking id or already start search with it, if not done, initialise search
if ( BodyTrackingIds[BodyOriginalIndex] != *CurrentBodies.BodiesInformation[iBody].trackingId )
{
BodyTrackingIds[BodyOriginalIndex] = *CurrentBodies.BodiesInformation[iBody].trackingId;
// StartedSearch[iBody] = true will be set in Thread::Run
}
FaceTrackerActuallySet[BodyOriginalIndex] = true;
}
int NbTrackedBody = 0;
for( iBody = 0; iBody < BODY_COUNT; iBody++ )
{
if ( FaceTrackerActuallySet[iBody] == false )
{
StartedSearch[iBody] = false;
BodyTrackingIds[iBody] = 0;
}
else
{
NbTrackedBody++;
}
}
}
/* virtual */ void FUNCTION_CALL_TYPE KinectFaceStream::Run()
{
if ( RecContext == nullptr )
{
fprintf( stderr, "No buffer available for faces\n" );
return;
}
IKinectSensor * pSensor = Caller.pSensor;
if ( pSensor == (IKinectSensor *)nullptr )
{
fprintf( stderr, "No kinect sensor available for faces\n" );
return;
}
HRESULT hr = S_OK;
struct timeb lTimestamp = { 0 };
// Face sources and readers
IFaceFrameReader * pFaceFrameReaders[BODY_COUNT] = { nullptr };
IFaceFrameSource* pFaceFrameSources[BODY_COUNT] = { nullptr };
// Open Face reader
DWORD FaceFrameFeatures = FaceFrameFeatures::FaceFrameFeatures_BoundingBoxInColorSpace
| FaceFrameFeatures::FaceFrameFeatures_BoundingBoxInInfraredSpace
| FaceFrameFeatures::FaceFrameFeatures_PointsInColorSpace
| FaceFrameFeatures::FaceFrameFeatures_RotationOrientation
| FaceFrameFeatures::FaceFrameFeatures_Happy
| FaceFrameFeatures::FaceFrameFeatures_RightEyeClosed
| FaceFrameFeatures::FaceFrameFeatures_LeftEyeClosed
| FaceFrameFeatures::FaceFrameFeatures_MouthOpen
| FaceFrameFeatures::FaceFrameFeatures_MouthMoved
| FaceFrameFeatures::FaceFrameFeatures_LookingAway
| FaceFrameFeatures::FaceFrameFeatures_Glasses
| FaceFrameFeatures::FaceFrameFeatures_FaceEngagement; // Everything
WAITABLE_HANDLE FramesWaiters[BODY_COUNT];
for (int i = 0; i < BODY_COUNT; i++)
{
FramesWaiters[i] = NULL;
// create the face frame source by specifying the required face frame features
HRESULT hr = CreateFaceFrameSource(pSensor, 0, FaceFrameFeatures, &pFaceFrameSources[i]);
if ( SUCCEEDED(hr) )
{
// open the corresponding reader
hr = pFaceFrameSources[i]->OpenReader(&pFaceFrameReaders[i]);
if ( SUCCEEDED(hr) )
{
if ( FAILED(pFaceFrameReaders[i]->SubscribeFrameArrived(&FramesWaiters[i])) )
{
}
}
}
}
// Allocated memory
unsigned char * lBuffer = (unsigned char*)RecContext->BufferData;
KinectFaces KF((unsigned char*)RecContext->BufferData);
Omiscid::SmartLocker SL_Protection(Protection, false );
UINT64 CurrentSearchFace[BODY_COUNT] = { 0 };
bool LastFrameContainedFaces = false;
while( !StopPending() )
{
// No face at this point
KF.ActualNbFaces = 0;
// Set tracking id to face tracker
SL_Protection.Lock();
for (int iFace = 0; iFace < BODY_COUNT; ++iFace)
{
CurrentSearchFace[iFace] = BodyTrackingIds[iFace];
if ( CurrentSearchFace[iFace] != 0 && StartedSearch[iFace] == false )
{
StartedSearch[iFace] = true;
pFaceFrameSources[iFace]->put_TrackingId(BodyTrackingIds[iFace]);
}
}
SL_Protection.Unlock();
// Go though faces
// int NBSearchesFaces = 0;
for (int iFace = 0; iFace < BODY_COUNT; ++iFace)
{
// Ok, we have a body tracking id, if not skip
if ( StartedSearch[iFace] == false )
{
continue;
}
// NBSearchesFaces++;
// Check if we have data from this face tracker
IFaceFrameArrivedEventArgs* pArgs = nullptr;
if ( FAILED(hr = pFaceFrameReaders[iFace]->GetFrameArrivedEventData(FramesWaiters[iFace], &pArgs)) )
{
continue;
}
// we do not use this, but release it
SafeRelease(pArgs);
// retrieve the latest face frame from this reader
IFaceFrame* pFaceFrame = nullptr;
// Omiscid::PerfElapsedTime ET;
hr = pFaceFrameReaders[iFace]->AcquireLatestFrame(&pFaceFrame);
// fprintf( stderr, "%f\n", ET.GetInSeconds() );
if ( FAILED(hr) || pFaceFrame == nullptr )
{
continue;
}
// Get timestamp
ftime(&lTimestamp);
BOOLEAN bFaceTracked = FALSE;
// check if a valid face is tracked in this face frame
hr = pFaceFrame->get_IsTrackingIdValid(&bFaceTracked);
if ( bFaceTracked == TRUE )
{
#ifdef SET_ASSOCIATED_BODY_TACKING_ID
KF.FacesInformation[KF.ActualNbFaces].Init(pFaceFrame, BodyTrackingIds[iFace] );
#else
KF.FacesInformation[KF.ActualNbFaces].Init(pFaceFrame);
#endif
KF.ActualNbFaces++;
pFaceFrame->get_RelativeTime(&(RecContext->LastFrameTime));
}
else
{
// no face is tracked, set trackingId
if ( BodyTrackingIds[iFace] != 0 )
{
pFaceFrameSources[iFace]->put_TrackingId(BodyTrackingIds[iFace]);
}
}
SafeRelease(pFaceFrame);
}
// fprintf( stderr, "%d (%d searched)\n", KF.ActualNbFaces, NBSearchesFaces );
if ( KF.ActualNbFaces == 0 )
{
if ( LastFrameContainedFaces == true )
{
// Caller.ProcessFaceFrame( KF, -1, lTimestamp, 0 );
}
LastFrameContainedFaces = false;
Omiscid::Thread::Sleep(5);
continue;
}
if ( KF.ActualNbFaces != 0 && RecContext != nullptr )
{
// To make source code looks like others
RawKinectRecording& rcs = *RecContext;
// Create quick a string containing number of bodies (even if always 6, can change later, hopefully to strictly less than 10)
char TmpNb[2];
TmpNb[0] = (char)(KF.ActualNbFaces+48); // Create ascii version of the number
TmpNb[1] = '\0';
// Save Data, first set buffer size (in term of number of faces)
rcs.BufferSize = KF.ActualNbFaces*KinectFace::FaceSize;
rcs.SaveDataAndIncreaseInputNumber( lTimestamp, TmpNb );
// Call only if we had faces
LastFrameContainedFaces = true;
Caller.ProcessFaceFrame( KF, rcs.InputNumber, lTimestamp, rcs.LastFrameTime );
// Input number was increased by 1 in SaveDataAndIncreaseInputNumber, increase it by the actual number of faces-1
rcs.InputNumber += KF.ActualNbFaces - 1;
}
}
}