summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorStéphane Lenclud <github@lenclud.com>2019-01-31 16:59:14 +0100
committerStéphane Lenclud <github@lenclud.com>2019-02-07 13:24:13 +0100
commitaf286a3fa5e1460faad85b816149ad1309ef3584 (patch)
tree988c7e6b6b22bfbe9585226422a74ee84533c70a
parenta774441fde00f0ce6c8387339c786e9e2f42f088 (diff)
Kinect: Now using HD API
-rw-r--r--tracker-kinect-face/tracker.cpp229
-rw-r--r--tracker-kinect-face/tracker.h18
2 files changed, 177 insertions, 70 deletions
diff --git a/tracker-kinect-face/tracker.cpp b/tracker-kinect-face/tracker.cpp
index 3fe3b8cc..9b03f492 100644
--- a/tracker-kinect-face/tracker.cpp
+++ b/tracker-kinect-face/tracker.cpp
@@ -3,11 +3,81 @@
#include "tracker.h"
-const double KinectFaceTracker::incr[6] =
+
+///
+bool IsValidRect(const RectI& aRect)
+{
+ if (aRect.Bottom != 0)
+ {
+ return true;
+ }
+
+ if (aRect.Left != 0)
+ {
+ return true;
+ }
+
+ if (aRect.Right != 0)
+ {
+ return true;
+ }
+
+ if (aRect.Top != 0)
+ {
+ return true;
+ }
+
+ return false;
+}
+
+///
+bool IsNullVetor(const Vector4& aVector)
+{
+ if (aVector.w != 0)
+ {
+ return false;
+ }
+
+ if (aVector.y != 0)
+ {
+ return false;
+ }
+
+ if (aVector.y != 0)
+ {
+ return false;
+ }
+
+ if (aVector.z != 0)
+ {
+ return false;
+ }
+
+ return true;
+}
+
+///
+bool IsNullPoint(const CameraSpacePoint& aPoint)
{
- 50, 40, 80,
- 70, 5, 3
-};
+ if (aPoint.X != 0)
+ {
+ return false;
+ }
+
+ if (aPoint.Y != 0)
+ {
+ return false;
+ }
+
+ if (aPoint.Z != 0)
+ {
+ return false;
+ }
+
+
+ return true;
+}
+
KinectFaceTracker::KinectFaceTracker():
m_pKinectSensor(nullptr),
@@ -17,11 +87,8 @@ KinectFaceTracker::KinectFaceTracker():
m_pBodyFrameReader(nullptr)
{
- for (int i = 0; i < BODY_COUNT; i++)
- {
- m_pFaceFrameSources[i] = nullptr;
- m_pFaceFrameReaders[i] = nullptr;
- }
+ m_pFaceFrameSource = nullptr;
+ m_pFaceFrameReader = nullptr;
// create heap storage for color pixel data in RGBX format
m_pColorRGBX = new RGBQUAD[cColorWidth * cColorHeight];
@@ -39,11 +106,8 @@ KinectFaceTracker::~KinectFaceTracker()
//SafeRelease(m_pD2DFactory);
// done with face sources and readers
- for (int i = 0; i < BODY_COUNT; i++)
- {
- SafeRelease(m_pFaceFrameSources[i]);
- SafeRelease(m_pFaceFrameReaders[i]);
- }
+ SafeRelease(m_pFaceFrameSource);
+ SafeRelease(m_pFaceFrameReader);
// done with body frame reader
SafeRelease(m_pBodyFrameReader);
@@ -79,46 +143,43 @@ module_status KinectFaceTracker::start_tracker(QFrame*)
# include <cstdlib>
#endif
+bool KinectFaceTracker::center()
+{
+ iFacePositionCenter = iFacePosition;
+ iFaceRotationCenter = iFaceRotation;
+ //TODO: Rotation center too
+ return true;
+}
+
+
void KinectFaceTracker::data(double *data)
{
const double dt = t.elapsed_seconds();
t.start();
-#ifdef EMIT_NAN
- if ((rand() % 4) == 0)
+
+ Update();
+ //TODO: check if data is valid
+
+ ExtractFaceRotationInDegrees(&iFaceRotationQuaternion, &iFaceRotation.X, &iFaceRotation.Y, &iFaceRotation.Z);
+
+ if (!IsNullPoint(iFacePosition) && !IsNullPoint(iFaceRotation))
{
- for (int i = 0; i < 6; i++)
- data[i] = 0. / 0.;
+ // We have valid tracking retain position and rotation
+ iLastFacePosition = iFacePosition;
+ iLastFaceRotation = iFaceRotation;
}
- else
-#endif
- for (int i = 0; i < 6; i++)
- {
- double x = last_x[i] + incr[i] * dt;
- if (x > 180)
- x = -360 + x;
- else if (x < -180)
- x = 360 + x;
- x = copysign(fmod(fabs(x), 360), x);
- last_x[i] = x;
-
- if (i >= 3)
- {
- data[i] = x;
- }
- else
- {
- data[i] = x * 100 / 180.;
- }
- }
+
+ // Feed our framework our last valid position and rotation
+ data[0] = (iLastFacePosition.X - iFacePositionCenter.X) * 100; // Convert to centimer to be in a range that suites OpenTrack.
+ data[1] = (iLastFacePosition.Y - iFacePositionCenter.Y) * 100;
+ data[2] = (iLastFacePosition.Z - iFacePositionCenter.Z) * 100;
+ // Yaw, picth, Roll
+ data[3] = 0-(iLastFaceRotation.X - iFaceRotationCenter.X); // Invert to be compatible with ED out-of-the-box
+ data[4] = (iLastFaceRotation.Y - iFaceRotationCenter.Y);
+ data[5] = (iLastFaceRotation.Z - iFaceRotationCenter.Z);
- Update();
- //TODO: check if data is valid
- data[0] = 0;
- data[1] = 0;
- data[2] = 0;
- ExtractFaceRotationInDegrees(&faceRotation,&data[3], &data[4], &data[5]);
}
@@ -131,7 +192,7 @@ void KinectFaceTracker::data(double *data)
/// <param name="pPitch">rotation about the X-axis</param>
/// <param name="pYaw">rotation about the Y-axis</param>
/// <param name="pRoll">rotation about the Z-axis</param>
-void KinectFaceTracker::ExtractFaceRotationInDegrees(const Vector4* pQuaternion, double* pYaw, double* pPitch, double* pRoll)
+void KinectFaceTracker::ExtractFaceRotationInDegrees(const Vector4* pQuaternion, float* pYaw, float* pPitch, float* pRoll)
{
double x = pQuaternion->x;
double y = pQuaternion->y;
@@ -215,12 +276,12 @@ HRESULT KinectFaceTracker::InitializeDefaultSensor()
if (SUCCEEDED(hr))
{
// create the face frame source by specifying the required face frame features
- hr = CreateFaceFrameSource(m_pKinectSensor, 0, c_FaceFrameFeatures, &m_pFaceFrameSources[i]);
+ hr = CreateHighDefinitionFaceFrameSource(m_pKinectSensor, &m_pFaceFrameSource);
}
if (SUCCEEDED(hr))
{
// open the corresponding reader
- hr = m_pFaceFrameSources[i]->OpenReader(&m_pFaceFrameReaders[i]);
+ hr = m_pFaceFrameSource->OpenReader(&m_pFaceFrameReader);
}
}
}
@@ -348,12 +409,43 @@ void KinectFaceTracker::ProcessFaces()
IBody* ppBodies[BODY_COUNT] = { 0 };
bool bHaveBodyData = SUCCEEDED(UpdateBodyData(ppBodies));
+ if (!bHaveBodyData)
+ {
+ return;
+ }
+
+ // TODO: Select closest body
+ // Just use the first body we find
+ BOOLEAN tracked;
+ int i = 0;
+ while (i < BODY_COUNT)
+ {
+ hr = ppBodies[i]->get_IsTracked(&tracked);
+ UINT64 trackingId = 0;
+
+ if (SUCCEEDED(hr) && tracked)
+ {
+ hr = ppBodies[i]->get_TrackingId(&trackingId);
+
+ if (SUCCEEDED(hr))
+ {
+ // Tell our face source to use the given body id
+ hr = m_pFaceFrameSource->put_TrackingId(trackingId);
+ break;
+ }
+
+ }
+
+ i++;
+ }
+
+
// iterate through each face reader
for (int iFace = 0; iFace < BODY_COUNT; ++iFace)
{
// retrieve the latest face frame from this reader
- IFaceFrame* pFaceFrame = nullptr;
- hr = m_pFaceFrameReaders[iFace]->AcquireLatestFrame(&pFaceFrame);
+ IHighDefinitionFaceFrame* pFaceFrame = nullptr;
+ hr = m_pFaceFrameReader->AcquireLatestFrame(&pFaceFrame);
BOOLEAN bFaceTracked = false;
if (SUCCEEDED(hr) && nullptr != pFaceFrame)
@@ -366,47 +458,54 @@ void KinectFaceTracker::ProcessFaces()
{
if (bFaceTracked)
{
- IFaceFrameResult* pFaceFrameResult = nullptr;
+ OutputDebugStringA("Tracking face!\n");
+
+ //IFaceFrameResult* pFaceFrameResult = nullptr;
+ IFaceAlignment* pFaceAlignment = nullptr;
+ CreateFaceAlignment(&pFaceAlignment); // TODO: check return?
RectI faceBox = { 0 };
- PointF facePoints[FacePointType::FacePointType_Count];
- DetectionResult faceProperties[FaceProperty::FaceProperty_Count];
- //D2D1_POINT_2F faceTextLayout;
+ //D2D1_POINT_2F faceTextLayout;
+
+ //hr = pFaceFrame->get_FaceFrameResult(&pFaceFrameResult);
- hr = pFaceFrame->get_FaceFrameResult(&pFaceFrameResult);
+ hr = pFaceFrame->GetAndRefreshFaceAlignmentResult(pFaceAlignment);
// need to verify if pFaceFrameResult contains data before trying to access it
- if (SUCCEEDED(hr) && pFaceFrameResult != nullptr)
+ if (SUCCEEDED(hr) && pFaceAlignment != nullptr)
{
- hr = pFaceFrameResult->get_FaceBoundingBoxInColorSpace(&faceBox);
+ hr = pFaceAlignment->get_FaceBoundingBox(&faceBox);
+ //pFaceFrameResult->get_FaceBoundingBoxInColorSpace();
if (SUCCEEDED(hr))
{
- hr = pFaceFrameResult->GetFacePointsInColorSpace(FacePointType::FacePointType_Count, facePoints);
+ //hr = pFaceFrameResult->GetFacePointsInColorSpace(FacePointType::FacePointType_Count, facePoints);
+ hr = pFaceAlignment->get_HeadPivotPoint(&iFacePosition);
}
if (SUCCEEDED(hr))
{
- hr = pFaceFrameResult->get_FaceRotationQuaternion(&faceRotation);
+ //hr = pFaceFrameResult->get_FaceRotationQuaternion(&faceRotation);
+ hr = pFaceAlignment->get_FaceOrientation(&iFaceRotationQuaternion);
}
if (SUCCEEDED(hr))
{
- hr = pFaceFrameResult->GetFaceProperties(FaceProperty::FaceProperty_Count, faceProperties);
+ //hr = pFaceFrameResult->GetFaceProperties(FaceProperty::FaceProperty_Count, faceProperties);
}
if (SUCCEEDED(hr))
{
- //hr = GetFaceTextPositionInColorSpace(ppBodies[iFace], &faceTextLayout);
+ //hr = GetFaceTextPositionInColorSpace(ppBodies[0], &faceTextLayout);
}
if (SUCCEEDED(hr))
{
// draw face frame results
- //m_pDrawDataStreams->DrawFaceFrameResults(iFace, &faceBox, facePoints, &faceRotation, faceProperties, &faceTextLayout);
+ //m_pDrawDataStreams->DrawFaceFrameResults(0, &faceBox, facePoints, &faceRotation, faceProperties, &faceTextLayout);
}
}
- SafeRelease(pFaceFrameResult);
+ SafeRelease(pFaceAlignment);
}
else
{
@@ -430,7 +529,7 @@ void KinectFaceTracker::ProcessFaces()
if (SUCCEEDED(hr))
{
// update the face frame source with the tracking ID
- m_pFaceFrameSources[iFace]->put_TrackingId(bodyTId);
+ m_pFaceFrameSource->put_TrackingId(bodyTId);
}
}
}
@@ -449,3 +548,5 @@ void KinectFaceTracker::ProcessFaces()
}
}
}
+
+
diff --git a/tracker-kinect-face/tracker.h b/tracker-kinect-face/tracker.h
index 88243b1f..cfadf997 100644
--- a/tracker-kinect-face/tracker.h
+++ b/tracker-kinect-face/tracker.h
@@ -32,10 +32,9 @@ public:
~KinectFaceTracker() override;
module_status start_tracker(QFrame *) override;
void data(double *data) override;
+ bool center() override;
private:
- static const double incr[6];
- double last_x[6]{};
Timer t;
// Kinect stuff
@@ -62,7 +61,7 @@ private:
HRESULT InitializeDefaultSensor();
void ProcessFaces();
HRESULT UpdateBodyData(IBody** ppBodies);
- void ExtractFaceRotationInDegrees(const Vector4* pQuaternion, double* pPitch, double* pYaw, double* pRoll);
+ void ExtractFaceRotationInDegrees(const Vector4* pQuaternion, float* pPitch, float* pYaw, float* pRoll);
// Current Kinect
IKinectSensor* m_pKinectSensor;
@@ -77,14 +76,21 @@ private:
IBodyFrameReader* m_pBodyFrameReader;
// Face sources
- IFaceFrameSource* m_pFaceFrameSources[BODY_COUNT];
+ IHighDefinitionFaceFrameSource* m_pFaceFrameSource;
// Face readers
- IFaceFrameReader* m_pFaceFrameReaders[BODY_COUNT];
+ IHighDefinitionFaceFrameReader* m_pFaceFrameReader;
//
RGBQUAD* m_pColorRGBX;
- Vector4 faceRotation;
+ CameraSpacePoint iLastFacePosition;
+ CameraSpacePoint iFacePosition;
+ CameraSpacePoint iFacePositionCenter;
+ Vector4 iFaceRotationQuaternion;
+ // As Yaw, Pitch, Roll
+ CameraSpacePoint iLastFaceRotation;
+ CameraSpacePoint iFaceRotation;
+ CameraSpacePoint iFaceRotationCenter;
};