質問編集履歴

2

文の修正

2017/12/05 04:31

投稿

hihihidesan
hihihidesan

スコア6

test CHANGED
@@ -1 +1 @@
1
- KinectV2プログラミング(C++)の改良
1
+ KinectV2プログラミング HDFace(C++)の改良
test CHANGED
@@ -1,6 +1,6 @@
1
1
  ###前提・実現したいこと
2
2
 
3
- KinectV2 HDfaceで1347点の顔特徴点を表示するプログラムを以下のURLように組んだのですが、
3
+ KinectV2 HDfaceで1347点の顔特徴点を表示するプログラムを以下のように組んだのですが、
4
4
 
5
5
  特徴点が多すぎるためKinect.Face.hで定義されたHighDetailFacePointsの数十点の特徴点のみを
6
6
 
@@ -8,13 +8,581 @@
8
8
 
9
9
 
10
10
 
11
- URL: https://github.com/K4W2-Book/K4W2-Book/blob/master/C%2B%2B(Native)/08_Face/KinectV2-Face-02/KinectV2/main.cpp
12
-
13
11
 
14
12
 
15
13
  ``````ここに言語を入力
16
14
 
15
+ #include <iostream>
16
+
17
+ #include <sstream>
18
+
19
+ #include <vector>
20
+
21
+ #include <array>
22
+
23
+ #define _USE_MATH_DEFINES
24
+
25
+ #include <cmath>
26
+
27
+ #include <atlbase.h>
28
+
29
+
30
+
31
+ #include <Windows.h>
32
+
33
+ #include <Kinect.h>
34
+
35
+ #include <Kinect.Face.h>
36
+
37
+
38
+
39
+ #include <opencv2/opencv.hpp>
40
+
41
+
42
+
43
+ #define ERROR_CHECK( ret ) \
44
+
45
+ if( FAILED( ret ) ){ \
46
+
47
+ std::stringstream ss; \
48
+
49
+ ss << "failed " #ret " " << std::hex << ret << std::endl; \
50
+
51
+ throw std::runtime_error( ss.str().c_str() ); \
52
+
53
+ }
54
+
55
+
56
+
57
+ class KinectApp
58
+
59
+ {
60
+
61
+ private:
62
+
63
+ CComPtr<IKinectSensor> kinect;
64
+
65
+ CComPtr<IColorFrameReader> colorFrameReader;
66
+
67
+ CComPtr<IBodyFrameReader> bodyFrameReader;
68
+
69
+ CComPtr<ICoordinateMapper> coordinateMapper;
70
+
71
+ std::vector<BYTE> colorBuffer;
72
+
73
+ int colorWidth;
74
+
75
+ int colorHeight;
76
+
77
+ unsigned int colorBytesPerPixel;
78
+
79
+ ColorImageFormat colorFormat = ColorImageFormat::ColorImageFormat_Bgra;
80
+
81
+ cv::Mat colorImage;
82
+
83
+
84
+
85
+ CComPtr<IHighDefinitionFaceFrameReader> hdFaceFrameReader;
86
+
87
+ CComPtr<IFaceModelBuilder> faceModelBuilder;
88
+
89
+ CComPtr<IFaceAlignment> faceAlignment;
90
+
91
+ CComPtr<IFaceModel> faceModel;
92
+
93
+ std::array<float, FaceShapeDeformations::FaceShapeDeformations_Count> shapeUnits;
94
+
95
+ UINT32 vertexCount;
96
+
97
+ UINT64 trackingId;
98
+
99
+ int trackingCount;
100
+
101
+ bool produced;
102
+
103
+
104
+
105
+ std::array<cv::Scalar, BODY_COUNT> colors;
106
+
107
+ int font = cv::FONT_HERSHEY_SIMPLEX;
108
+
109
+
110
+
111
+ public:
112
+
113
+ void initialize()
114
+
115
+ {
116
+
117
+ ERROR_CHECK( GetDefaultKinectSensor( &kinect ) );
118
+
119
+ ERROR_CHECK( kinect->Open() );
120
+
121
+ BOOLEAN isOpen;
122
+
123
+ ERROR_CHECK( kinect->get_IsOpen( &isOpen ) );
124
+
125
+ if( !isOpen ){
126
+
127
+ throw std::runtime_error( "failed IKinectSensor::get_IsOpen( &isOpen )" );
128
+
129
+ }
130
+
131
+
132
+
133
+ ERROR_CHECK( kinect->get_CoordinateMapper( &coordinateMapper ) );
134
+
135
+ CComPtr<IColorFrameSource> colorFrameSource;
136
+
137
+ ERROR_CHECK( kinect->get_ColorFrameSource( &colorFrameSource ) );
138
+
139
+ ERROR_CHECK( colorFrameSource->OpenReader( &colorFrameReader ) );
140
+
141
+ CComPtr<IFrameDescription> colorFrameDescription;
142
+
143
+ ERROR_CHECK( colorFrameSource->CreateFrameDescription( colorFormat, &colorFrameDescription ) );
144
+
145
+ ERROR_CHECK( colorFrameDescription->get_Width( &colorWidth ) );
146
+
147
+ ERROR_CHECK( colorFrameDescription->get_Height( &colorHeight ) );
148
+
149
+ ERROR_CHECK( colorFrameDescription->get_BytesPerPixel( &colorBytesPerPixel ) );
150
+
151
+ colorBuffer.resize( colorWidth * colorHeight * colorBytesPerPixel );
152
+
153
+ CComPtr<IBodyFrameSource> bodyFrameSource;
154
+
155
+ ERROR_CHECK( kinect->get_BodyFrameSource( &bodyFrameSource ) );
156
+
157
+ ERROR_CHECK( bodyFrameSource->OpenReader( &bodyFrameReader ) );
158
+
159
+
160
+
161
+ initializeHDFace();
162
+
163
+
164
+
165
+ // Lookup Table
166
+
167
+ colors[0] = cv::Scalar( 255, 0, 0 );
168
+
169
+ colors[1] = cv::Scalar( 0, 255, 0 );
170
+
171
+ colors[2] = cv::Scalar( 0, 0, 255 );
172
+
173
+ colors[3] = cv::Scalar( 255, 255, 0 );
174
+
175
+ colors[4] = cv::Scalar( 255, 0, 255 );
176
+
177
+ colors[5] = cv::Scalar( 0, 255, 255 );
178
+
179
+ }
180
+
181
+
182
+
183
+ void run()
184
+
185
+ {
186
+
187
+ while( 1 ){
188
+
189
+ update();
190
+
191
+ draw();
192
+
193
+
194
+
195
+ int key = cv::waitKey( 10 );
196
+
197
+ if( key == VK_ESCAPE ){
198
+
199
+ cv::destroyAllWindows();
200
+
201
+ break;
202
+
203
+ }
204
+
205
+ }
206
+
207
+ }
208
+
209
+
210
+
211
+ private:
212
+
213
+ void initializeHDFace()
214
+
215
+ {
216
+
217
+ CComPtr<IHighDefinitionFaceFrameSource> hdFaceFrameSource;
218
+
219
+ ERROR_CHECK( CreateHighDefinitionFaceFrameSource( kinect, &hdFaceFrameSource ) );
220
+
221
+
222
+
223
+ ERROR_CHECK( hdFaceFrameSource->OpenReader( &hdFaceFrameReader ) );
224
+
225
+
226
+
227
+ ERROR_CHECK( CreateFaceAlignment( &faceAlignment ) );
228
+
229
+
230
+
231
+ ERROR_CHECK( CreateFaceModel( 1.0f, FaceShapeDeformations::FaceShapeDeformations_Count, &shapeUnits[0], &faceModel ) );
232
+
233
+ ERROR_CHECK( GetFaceModelVertexCount( &vertexCount ) );
234
+
235
+
236
+
237
+ FaceModelBuilderAttributes attribures = FaceModelBuilderAttributes::FaceModelBuilderAttributes_None;
238
+
239
+ ERROR_CHECK( hdFaceFrameSource->OpenModelBuilder( attribures, &faceModelBuilder ) );
240
+
241
+ ERROR_CHECK( faceModelBuilder->BeginFaceDataCollection() );
242
+
243
+ }
244
+
245
+
246
+
247
+ void update()
248
+
249
+ {
250
+
251
+ updateColorFrame();
252
+
253
+ updateBodyFrame();
254
+
255
+ updateHDFaceFrame();
256
+
257
+ }
258
+
259
+
260
+
261
+ void updateColorFrame()
262
+
263
+ {
264
+
265
+ CComPtr<IColorFrame> colorFrame;
266
+
267
+ HRESULT ret = colorFrameReader->AcquireLatestFrame( &colorFrame );
268
+
269
+ if( FAILED( ret ) ){
270
+
271
+ return;
272
+
273
+ }
274
+
275
+
276
+
277
+ ERROR_CHECK( colorFrame->CopyConvertedFrameDataToArray( static_cast<UINT>( colorBuffer.size() ), &colorBuffer[0], colorFormat ) );
278
+
279
+
280
+
281
+ colorImage = cv::Mat( colorHeight, colorWidth, CV_8UC4, &colorBuffer[0] );
282
+
283
+ }
284
+
285
+
286
+
287
+ void updateBodyFrame()
288
+
289
+ {
290
+
291
+ CComPtr<IBodyFrame> bodyFrame;
292
+
293
+ HRESULT ret = bodyFrameReader->AcquireLatestFrame( &bodyFrame );
294
+
295
+ if( FAILED( ret ) ){
296
+
297
+ return;
298
+
299
+ }
300
+
301
+
302
+
303
+ std::array<CComPtr<IBody>, BODY_COUNT> bodies;
304
+
305
+ ERROR_CHECK( bodyFrame->GetAndRefreshBodyData( BODY_COUNT, &bodies[0] ) );
306
+
307
+
308
+
309
+ findClosestBody( bodies );
310
+
311
+ }
312
+
313
+
314
+
315
+ inline void findClosestBody( const std::array<CComPtr<IBody>, BODY_COUNT>& bodies )
316
+
317
+ {
318
+
319
+ float closest = FLT_MAX;
320
+
321
+ for( int count = 0; count < BODY_COUNT; count++ ){
322
+
323
+ CComPtr<IBody> body = bodies[count];
324
+
325
+ BOOLEAN tracked;
326
+
327
+ ERROR_CHECK( body->get_IsTracked( &tracked ) );
328
+
329
+ if( !tracked ){
330
+
331
+ continue;
332
+
333
+ }
334
+
335
+
336
+
337
+ std::array<Joint, JointType::JointType_Count> joints;
338
+
339
+ ERROR_CHECK( body->GetJoints( JointType::JointType_Count, &joints[0] ) );
340
+
341
+ Joint joint = joints[JointType::JointType_Head];
342
+
343
+ if( joint.TrackingState == TrackingState::TrackingState_NotTracked ){
344
+
345
+ continue;
346
+
347
+ }
348
+
349
+
350
+
351
+ CameraSpacePoint point = joint.Position;
352
+
353
+ float distance = std::sqrt( std::pow( point.X, 2 ) + std::pow( point.Y, 2 ) + std::pow( point.Z, 2 ) );
354
+
355
+ if( closest <= distance ){
356
+
357
+ continue;
358
+
359
+ }
360
+
361
+ closest = distance;
362
+
363
+
364
+
365
+ UINT64 id;
366
+
367
+ ERROR_CHECK( body->get_TrackingId( &id ) );
368
+
369
+ if( trackingId != id ){
370
+
371
+ trackingId = id;
372
+
373
+ trackingCount = count;
374
+
375
+ produced = false;
376
+
377
+
378
+
379
+
380
+
381
+ CComPtr<IHighDefinitionFaceFrameSource> hdFaceFrameSource;
382
+
383
+ ERROR_CHECK( hdFaceFrameReader->get_HighDefinitionFaceFrameSource( &hdFaceFrameSource ) );
384
+
385
+ ERROR_CHECK( hdFaceFrameSource->put_TrackingId( trackingId ) );
386
+
387
+ }
388
+
389
+ }
390
+
391
+ }
392
+
393
+
394
+
395
+ void updateHDFaceFrame()
396
+
397
+ {
398
+
399
+ CComPtr<IHighDefinitionFaceFrame> hdFaceFrame;
400
+
401
+ HRESULT ret = hdFaceFrameReader->AcquireLatestFrame( &hdFaceFrame );
402
+
403
+ if( FAILED( ret ) ){
404
+
405
+ return;
406
+
407
+ }
408
+
409
+
410
+
411
+ BOOLEAN tracked;
412
+
413
+ ERROR_CHECK( hdFaceFrame->get_IsFaceTracked( &tracked ) );
414
+
415
+ if( !tracked ){
416
+
417
+ return;
418
+
419
+ }
420
+
421
+
422
+
423
+ ERROR_CHECK( hdFaceFrame->GetAndRefreshFaceAlignmentResult( faceAlignment ) );
424
+
425
+ if( faceAlignment != nullptr ){
426
+
427
+ // Face Modelのフィッティング
428
+
429
+ buildFaceModel();
430
+
431
+
432
+
433
+ // 結果を取得、描画
434
+
435
+ result();
436
+
437
+ }
438
+
439
+ }
440
+
441
+
442
+
443
+ inline void buildFaceModel()
444
+
445
+ {
446
+
447
+ if( produced ){
448
+
449
+ cv::putText( colorImage, "Status : Complete", cv::Point( 50, 50 ), font, 1.0f, colors[trackingCount], 2, CV_AA );
450
+
451
+ return;
452
+
453
+ }
454
+
455
+
456
+
457
+ FaceModelBuilderCollectionStatus collection;
458
+
459
+ ERROR_CHECK( faceModelBuilder->get_CollectionStatus( &collection ) );
460
+
461
+ if( collection ){
462
+
463
+ // コレクション状態
464
+
465
+ cv::putText( colorImage, "Status : " + std::to_string( collection ), cv::Point( 50, 50 ), font, 1.0f, colors[trackingCount], 2, CV_AA );
466
+
467
+ std::string status = status2string( collection );
468
+
469
+ cv::putText( colorImage, status, cv::Point( 50, 80 ), font, 1.0f, colors[trackingCount], 2, CV_AA );
470
+
471
+
472
+
473
+ // キャプチャー状態
474
+
475
+ FaceModelBuilderCaptureStatus capture;
476
+
477
+ ERROR_CHECK( faceModelBuilder->get_CaptureStatus( &capture ) );
478
+
479
+ status = status2string( capture );
480
+
481
+ cv::putText( colorImage, status, cv::Point( 50, 110 ), font, 1.0f, colors[trackingCount], 2, CV_AA );
482
+
483
+
484
+
485
+ return;
486
+
487
+ }
488
+
489
+
490
+
491
+ CComPtr<IFaceModelData> faceModelData;
492
+
493
+ ERROR_CHECK( faceModelBuilder->GetFaceData( &faceModelData ) );
494
+
495
+ if( faceModelData != nullptr ){
496
+
497
+ ERROR_CHECK( faceModelData->ProduceFaceModel( &faceModel ) );
498
+
499
+ produced = true;
500
+
501
+ }
502
+
503
+ }
504
+
505
+
506
+
507
+ inline std::string status2string( const FaceModelBuilderCollectionStatus collection )
508
+
509
+ {
510
+
511
+ //文字数の都合上省略します。
512
+
513
+ return status;
514
+
515
+ }
516
+
517
+
518
+
519
+ inline std::string status2string( const FaceModelBuilderCaptureStatus capture )
520
+
521
+ {
522
+
523
+ //文字数の都合上省略します。
524
+
525
+ }
526
+
527
+
528
+
529
+ inline void result()
530
+
531
+ {
532
+
533
+ //文字数の都合上省略します。
534
+
535
+ }
536
+
537
+
538
+
539
+ void draw()
540
+
541
+ {
542
+
543
+ drawHDFaceFrame();
544
+
545
+ }
546
+
547
+
548
+
549
+ void drawHDFaceFrame()
550
+
551
+ {
552
+
553
+ if( !colorImage.empty() ){
554
+
555
+ cv::imshow( "HDFace", colorImage );
556
+
557
+ }
558
+
559
+ }
560
+
561
+ };
562
+
563
+
564
+
565
+ void main()
566
+
567
+ {
568
+
17
- C++
569
+ try{
570
+
571
+ KinectApp app;
572
+
573
+ app.initialize();
574
+
575
+ app.run();
576
+
577
+ }
578
+
579
+ catch( std::exception& ex ){
580
+
581
+ std::cout << ex.what() << std::endl;
582
+
583
+ }
584
+
585
+ }
18
586
 
19
587
  ```
20
588
 

1

2017/12/05 04:31

投稿

hihihidesan
hihihidesan

スコア6

test CHANGED
File without changes
test CHANGED
File without changes