@@ -30,6 +30,7 @@ class KinectWrapper
3030
3131    WAITABLE_HANDLE h_statusChangedEvent;
3232    WAITABLE_HANDLE h_bodyFrameEvent;
33+     WAITABLE_HANDLE h_colorFrameEvent;
3334    bool  newBodyFrameArrived = false ;
3435
3536    std::array<JointOrientation, JointType_Count> bone_orientations_;
@@ -39,6 +40,7 @@ class KinectWrapper
3940
4041    inline  static  bool  initialized_ = false ;
4142    bool  skeleton_tracked_ = false ;
43+     bool  rgb_stream_enabled_ = false ;
4244
4345    void  updater ()
4446    {
@@ -83,6 +85,20 @@ class KinectWrapper
8385        }
8486    }
8587
88+     void  updateColorData ()
89+     {
90+         if  (!colorFrameReader)return ; //  Give up already
91+ 
92+         IColorFrame* colorFrame = nullptr ;
93+         colorFrameReader->AcquireLatestFrame (&colorFrame);
94+ 
95+         if  (!colorFrame) return ;
96+         ResetBuffer (CameraBufferSize ()); //  Allocate buffer for image for copy
97+ 
98+         colorFrame->CopyConvertedFrameDataToArray (
99+             CameraBufferSize (), color_buffer_, ColorImageFormat_Bgra);
100+     }
101+ 
86102    bool  initKinect ()
87103    {
88104        //  Get a working Kinect Sensor
@@ -130,6 +146,22 @@ class KinectWrapper
130146        if  (bodyFrameSource) bodyFrameSource->Release ();
131147    }
132148
149+     void  initializeColor ()
150+     {
151+         if  (colorFrameReader)
152+             colorFrameReader->Release ();
153+ 
154+         IColorFrameSource* colorFrameSource;
155+         kinectSensor->get_ColorFrameSource (&colorFrameSource);
156+         colorFrameSource->OpenReader (&colorFrameReader);
157+ 
158+         //  Newfangled event based frame capture
159+         //  https://github.com/StevenHickson/PCL_Kinect2SDK/blob/master/src/Microsoft_grabber2.cpp
160+         h_colorFrameEvent = (WAITABLE_HANDLE)CreateEvent (nullptr , FALSE , FALSE , nullptr );
161+         colorFrameReader->SubscribeFrameArrived (&h_colorFrameEvent);
162+         if  (colorFrameSource) colorFrameSource->Release ();
163+     }
164+ 
133165    void  terminateSkeleton ()
134166    {
135167        if  (!bodyFrameReader)return ; //  No need to do anything
@@ -150,6 +182,26 @@ class KinectWrapper
150182        bodyFrameReader = nullptr ;
151183    }
152184
185+     void  terminateColor ()
186+     {
187+         if  (!colorFrameReader)return ; //  No need to do anything
188+         if  (FAILED (colorFrameReader->UnsubscribeFrameArrived (h_colorFrameEvent)))
189+         {
190+             throw  std::exception (" Couldn't unsubscribe frame!"  );
191+         }
192+         __try
193+         {
194+             CloseHandle ((HANDLE)h_colorFrameEvent);
195+             colorFrameReader->Release ();
196+         }
197+         __except  (EXCEPTION_EXECUTE_HANDLER)
198+         {
199+             //  ignored
200+         }
201+         h_colorFrameEvent = NULL ;
202+         colorFrameReader = nullptr ;
203+     }
204+ 
153205    HRESULT kinect_status_result ()
154206    {
155207        BOOLEAN avail;
@@ -246,6 +298,7 @@ class KinectWrapper
246298            if  (!initialized_) return  1 ;
247299
248300            initializeSkeleton ();
301+             initializeColor ();
249302
250303            //  Recreate the updater thread
251304            if  (!updater_thread_)
@@ -306,6 +359,24 @@ class KinectWrapper
306359                            pArgs->Release (); //  Release the frame
307360                        }
308361                    }
362+ 
363+                 if  (h_colorFrameEvent && rgb_stream_enabled_)
364+                     if  (HANDLE handles[] = {reinterpret_cast <HANDLE>(h_colorFrameEvent)};
365+                         //  Wait for a frame to arrive, give up after >3s of nothing
366+                         MsgWaitForMultipleObjects (_countof (handles), handles,
367+                                                   false , 3000 , QS_ALLINPUT) == WAIT_OBJECT_0)
368+                     {
369+                         IColorFrameArrivedEventArgs* pArgs = nullptr ;
370+                         if  (colorFrameReader &&
371+                             SUCCEEDED (colorFrameReader->GetFrameArrivedEventData (h_colorFrameEvent, &pArgs)))
372+                         {
373+                             [&,this ](IColorFrameReader& sender, IColorFrameArrivedEventArgs& eventArgs)
374+                             {
375+                                 updateColorData ();
376+                             }(*colorFrameReader, *pArgs);
377+                             pArgs->Release (); //  Release the frame
378+                         }
379+                     }
309380            }
310381        }
311382    }
@@ -319,6 +390,7 @@ class KinectWrapper
319390            {
320391                //  Protect from null call
321392                terminateSkeleton ();
393+                 terminateColor ();
322394
323395                return  [&, this ]
324396                {
@@ -376,13 +448,74 @@ class KinectWrapper
376448        return  skeleton_positions_;
377449    }
378450
451+     std::tuple<BYTE*, int > color_buffer ()
452+     {
453+         return  std::make_tuple (color_buffer_, size_in_bytes_last_);
454+     }
455+ 
379456    bool  skeleton_tracked ()
380457    {
381458        return  skeleton_tracked_;
382459    }
383460
461+     void  camera_enabled (bool  enabled)
462+     {
463+         rgb_stream_enabled_ = enabled;
464+     }
465+ 
466+     bool  camera_enabled (void )
467+     {
468+         return  rgb_stream_enabled_;
469+     }
470+ 
384471    int  KinectJointType (int  kinectJointType)
385472    {
386473        return  KinectJointTypeDictionary.at (static_cast <JointType>(kinectJointType));
387474    }
475+ 
476+     std::pair<int , int > CameraImageSize ()
477+     {
478+         return  std::make_pair (1920 , 1080 );
479+     }
480+ 
481+     unsigned  long  CameraBufferSize ()
482+     {
483+         const  auto & [width, height] = CameraImageSize ();
484+         return  width * height * 4 ;
485+     }
486+ 
487+     std::pair<int , int > MapCoordinate (const  CameraSpacePoint& skeletonPoint)
488+     {
489+         ColorSpacePoint spacePoint; //  Holds the mapped coordinate
490+         const  auto & result = coordMapper->MapCameraPointToColorSpace (skeletonPoint, &spacePoint);
491+ 
492+         return  SUCCEEDED (result) && !std::isnan (spacePoint.X ) && !std::isnan (spacePoint.Y )
493+                    ? std::make_pair (spacePoint.X , spacePoint.Y ) //  Send the mapped ones
494+                    : std::make_pair (-1 , -1 ); //  Unknown coordinates - fall back to default drawing
495+     }
496+ 
497+ private: 
498+     DWORD size_in_bytes_ = 0 ;
499+     DWORD size_in_bytes_last_ = 0 ;
500+     BYTE* color_buffer_ = nullptr ;
501+ 
502+     BYTE* ResetBuffer (UINT size)
503+     {
504+         if  (!color_buffer_ || size_in_bytes_ != size)
505+         {
506+             if  (color_buffer_)
507+             {
508+                 delete[]  color_buffer_;
509+                 color_buffer_ = nullptr ;
510+             }
511+ 
512+             if  (0  != size)
513+             {
514+                 color_buffer_ = new  BYTE[size];
515+             }
516+             size_in_bytes_ = size;
517+         }
518+ 
519+         return  color_buffer_;
520+     }
388521};
0 commit comments