Example #1
0
        /// <summary>
        /// Gets the 3D shape associated with the result
        /// </summary>
        /// <param name="faceTrackFrame">
        /// result object
        /// </param>
        /// <returns>
        /// the 3d shape
        /// </returns>
        public Vector3DF[] Get3DShape(FaceTrackFrame faceTrackFrame)
        {
            IntPtr shapeUnitCoeffPtr;
            uint shapeUnitCount = 0;
            IntPtr animUnitCoeffPtr;
            uint animUnitPointsCount;
            bool hasSuConverged;
            float scale;

            faceTrackFrame.ResultPtr.GetAUCoefficients(out animUnitCoeffPtr, out animUnitPointsCount);
            this.faceTracker.FaceTrackerPtr.GetShapeUnits(out scale, out shapeUnitCoeffPtr, ref shapeUnitCount, out hasSuConverged);

            return this.Get3DShape(
                shapeUnitCoeffPtr,
                shapeUnitCount,
                animUnitCoeffPtr,
                animUnitPointsCount,
                faceTrackFrame.Scale,
                faceTrackFrame.Rotation,
                faceTrackFrame.Translation);
        }
Example #2
0
        public PointF[] GetProjected3DShape(float zoomFactor, Point viewOffset, FaceTrackFrame faceTrackFrame)
        {
            this.CheckPtrAndThrow();
            IntPtr shapeUnitCoeffPtr;
            uint shapeUnitCount = 0;
            IntPtr animUnitCoeffPtr;
            uint animUnitPointsCount;
            bool hasSuConverged;
            float scale;

            faceTrackFrame.ResultPtr.GetAUCoefficients(out animUnitCoeffPtr, out animUnitPointsCount);
            this.faceTracker.FaceTrackerPtr.GetShapeUnits(out scale, out shapeUnitCoeffPtr, ref shapeUnitCount, out hasSuConverged);

            return this.GetProjected3DShape(
                this.faceTracker.ColorCameraConfig,
                zoomFactor,
                viewOffset,
                shapeUnitCoeffPtr,
                shapeUnitCount,
                animUnitCoeffPtr,
                animUnitPointsCount,
                faceTrackFrame.Scale,
                faceTrackFrame.Rotation,
                faceTrackFrame.Translation);
        }
Example #3
0
        /// <summary>
        /// Helper method that does the core instantiation & initialization of face tracking engine
        /// </summary>
        /// <param name="newColorCameraConfig">Color camera configuration</param>
        /// <param name="newDepthCameraConfig">Depth camera configuration</param>
        /// <param name="colorImagePtr">Allows face tracking engine to read color image from native memory pointer. 
        /// If set to IntPtr.Zero, image data needs to be provided for tracking to this instance. </param>
        /// <param name="depthImagePtr">Allows face tracking engine to read depth image from native memory pointer. 
        /// If set to IntPtr.Zero, image data needs to be provided for tracking to this instance.</param>
        /// <param name="newRegisterDepthToColorDelegate">Callback which maps of depth to color pixels</param>
        private void Initialize(
            CameraConfig newColorCameraConfig, 
            CameraConfig newDepthCameraConfig, 
            IntPtr colorImagePtr, 
            IntPtr depthImagePtr, 
            FaceTrackingRegisterDepthToColor newRegisterDepthToColorDelegate)
        {
            if (newColorCameraConfig == null)
            {
                throw new ArgumentNullException("newColorCameraConfig");
            }

            if (newDepthCameraConfig == null)
            {
                throw new ArgumentNullException("newDepthCameraConfig");
            }

            if (newRegisterDepthToColorDelegate == null)
            {
                throw new ArgumentNullException("newRegisterDepthToColorDelegate");
            }

            // initialize perf counters
            this.totalTracks = 0;
            this.trackStopwatch.Reset();

            // get configuration & trace settings
            this.traceLevel = new TraceSwitch(FaceTrackTraceSwitchName, FaceTrackTraceSwitchName).Level;

            this.videoCameraConfig = newColorCameraConfig;
            this.depthCameraConfig = newDepthCameraConfig;
            this.registerDepthToColorDelegate = newRegisterDepthToColorDelegate;

            this.faceTrackerInteropPtr = NativeMethods.FTCreateFaceTracker(IntPtr.Zero);
            if (this.faceTrackerInteropPtr == null)
            {
                throw new InsufficientMemoryException("Cannot create face tracker.");
            }

            IntPtr funcPtr = Marshal.GetFunctionPointerForDelegate(this.registerDepthToColorDelegate);
            if (funcPtr == IntPtr.Zero)
            {
                throw new InsufficientMemoryException("Cannot setup callback for retrieving color to depth pixel mapping");
            }

            int hr = this.faceTrackerInteropPtr.Initialize(this.videoCameraConfig, this.depthCameraConfig, funcPtr, null);
            if (hr != 0)
            {
                throw new InvalidOperationException(
                    string.Format(CultureInfo.CurrentCulture, "Failed to initialize face tracker - Error code from native=0x{0:X}", hr));
            }

            this.frame = this.CreateResult(out hr);
            if (this.frame == null || hr != 0)
            {
                throw new InvalidOperationException(
                    string.Format(CultureInfo.CurrentCulture, "Failed to create face tracking result. Error code from native=0x{0:X}", hr));
            }

            this.colorFaceTrackingImage = new Image();
            if (colorImagePtr == IntPtr.Zero)
            {
                this.colorFaceTrackingImage.Allocate(
                    this.videoCameraConfig.Width, this.videoCameraConfig.Height, this.videoCameraConfig.ImageFormat);
            }
            else
            {
                this.colorFaceTrackingImage.Attach(
                    this.videoCameraConfig.Width,
                    this.videoCameraConfig.Height,
                    colorImagePtr,
                    this.videoCameraConfig.ImageFormat,
                    this.videoCameraConfig.Stride);
            }

            this.depthFaceTrackingImage = new Image();
            if (depthImagePtr == IntPtr.Zero)
            {
                this.depthFaceTrackingImage.Allocate(
                    this.depthCameraConfig.Width, this.depthCameraConfig.Height, this.depthCameraConfig.ImageFormat);
            }
            else
            {
                this.depthFaceTrackingImage.Attach(
                    this.depthCameraConfig.Width,
                    this.depthCameraConfig.Height,
                    depthImagePtr,
                    this.depthCameraConfig.ImageFormat,
                    this.depthCameraConfig.Stride);
            }
        }
Example #4
0
        /// <summary>
        /// Allows calling dispose explicitly or from the finalizer
        /// </summary>
        /// <param name="disposing">true to release both managed and unmanaged resources; false to release only unmanaged resources</param>
        protected virtual void Dispose(bool disposing)
        {
            if (!this.disposed)
            {
                string traceStr = string.Format(
                    CultureInfo.InvariantCulture,
                    "FaceTracker::Dispose() - TotalTracks={0}, TotalSuccessTracks={1}, TimePerTrack={2:F3}ms, TimePerSuccessTrack={3:F3}ms, TimePerDataCopy={4:F3}ms, TimePerStartOrContinueTracking={5:F3}ms",
                    this.totalTracks,
                    this.totalSuccessTracks,
                    this.totalTracks > 0 ? (double)this.trackStopwatch.ElapsedMilliseconds / this.totalTracks : 0,
                    this.totalSuccessTracks > 0 ? (double)this.totalSuccessTrackMs / this.totalSuccessTracks : 0,
                    this.totalTracks > 0 ? (double)this.copyStopwatch.ElapsedMilliseconds / this.totalTracks : 0,
                    this.totalTracks > 0 ? (double)this.startOrContinueTrackingStopwatch.ElapsedMilliseconds / this.totalTracks : 0);
            #if DEBUG
                Debug.WriteLine(traceStr);
            #else
                Trace.WriteLineIf(traceLevel >= TraceLevel.Info, traceStr);
            #endif
                if (this.faceModel != null)
                {
                    this.faceModel.Dispose();
                    this.faceModel = null;
                }

                if (this.frame != null)
                {
                    this.frame.Dispose();
                    this.frame = null;
                }

                if (this.colorFaceTrackingImage != null)
                {
                    this.colorFaceTrackingImage.Dispose();
                    this.colorFaceTrackingImage = null;
                }

                if (this.depthFaceTrackingImage != null)
                {
                    this.depthFaceTrackingImage.Dispose();
                    this.depthFaceTrackingImage = null;
                }

                if (this.faceTrackerInteropPtr != null)
                {
                    Marshal.FinalReleaseComObject(this.faceTrackerInteropPtr);
                    this.faceTrackerInteropPtr = null;
                }

                this.disposed = true;
            }
        }
Example #5
0
        /// <summary>
        /// Creates a frame object instance. Can be used for caching of the face tracking
        /// frame. FaceTrackFrame should be disposed after use.
        /// </summary>
        /// <returns>
        /// newly created frame object
        /// </returns>
        internal FaceTrackFrame CreateResult(out int hr)
        {
            IFTResult faceTrackResultPtr;
            FaceTrackFrame faceTrackFrame = null;

            this.CheckPtrAndThrow();
            hr = this.faceTrackerInteropPtr.CreateFTResult(out faceTrackResultPtr);
            if (faceTrackResultPtr != null)
            {
                faceTrackFrame = new FaceTrackFrame(faceTrackResultPtr, this);
            }

            return faceTrackFrame;
        }
Example #6
0
        /// <summary>
        /// Helper method that does the core instantiation & initialization of face tracking engine
        /// </summary>
        /// <param name="newColorCameraConfig">Color camera configuration</param>
        /// <param name="newDepthCameraConfig">Depth camera configuration</param>
        /// <param name="colorImagePtr">Allows face tracking engine to read color image from native memory pointer.
        /// If set to IntPtr.Zero, image data needs to be provided for tracking to this instance. </param>
        /// <param name="depthImagePtr">Allows face tracking engine to read depth image from native memory pointer.
        /// If set to IntPtr.Zero, image data needs to be provided for tracking to this instance.</param>
        /// <param name="newRegisterDepthToColorDelegate">Callback which maps of depth to color pixels</param>
        private void Initialize(
            CameraConfig newColorCameraConfig,
            CameraConfig newDepthCameraConfig,
            IntPtr colorImagePtr,
            IntPtr depthImagePtr,
            FaceTrackingRegisterDepthToColor newRegisterDepthToColorDelegate)
        {
            if (newColorCameraConfig == null)
            {
                throw new ArgumentNullException("newColorCameraConfig");
            }

            if (newDepthCameraConfig == null)
            {
                throw new ArgumentNullException("newDepthCameraConfig");
            }

            if (newRegisterDepthToColorDelegate == null)
            {
                throw new ArgumentNullException("newRegisterDepthToColorDelegate");
            }

            // initialize perf counters
            this.totalTracks = 0;
            this.trackStopwatch.Reset();

            // get configuration & trace settings
            this.traceLevel = new TraceSwitch(FaceTrackTraceSwitchName, FaceTrackTraceSwitchName).Level;

            this.videoCameraConfig            = newColorCameraConfig;
            this.depthCameraConfig            = newDepthCameraConfig;
            this.registerDepthToColorDelegate = newRegisterDepthToColorDelegate;

            this.faceTrackerInteropPtr = NativeMethods.FTCreateFaceTracker(IntPtr.Zero);
            if (this.faceTrackerInteropPtr == null)
            {
                throw new InsufficientMemoryException("Cannot create face tracker.");
            }

            IntPtr funcPtr = Marshal.GetFunctionPointerForDelegate(this.registerDepthToColorDelegate);

            if (funcPtr == IntPtr.Zero)
            {
                throw new InsufficientMemoryException("Cannot setup callback for retrieving color to depth pixel mapping");
            }

            int hr = this.faceTrackerInteropPtr.Initialize(this.videoCameraConfig, this.depthCameraConfig, funcPtr, null);

            if (hr != 0)
            {
                throw new InvalidOperationException(
                          string.Format(CultureInfo.CurrentCulture, "Failed to initialize face tracker - Error code from native=0x{0:X}", hr));
            }

            this.frame = this.CreateResult(out hr);
            if (this.frame == null || hr != 0)
            {
                throw new InvalidOperationException(
                          string.Format(CultureInfo.CurrentCulture, "Failed to create face tracking result. Error code from native=0x{0:X}", hr));
            }

            this.colorFaceTrackingImage = new Image();
            if (colorImagePtr == IntPtr.Zero)
            {
                this.colorFaceTrackingImage.Allocate(
                    this.videoCameraConfig.Width, this.videoCameraConfig.Height, this.videoCameraConfig.ImageFormat);
            }
            else
            {
                this.colorFaceTrackingImage.Attach(
                    this.videoCameraConfig.Width,
                    this.videoCameraConfig.Height,
                    colorImagePtr,
                    this.videoCameraConfig.ImageFormat,
                    this.videoCameraConfig.Stride);
            }

            this.depthFaceTrackingImage = new Image();
            if (depthImagePtr == IntPtr.Zero)
            {
                this.depthFaceTrackingImage.Allocate(
                    this.depthCameraConfig.Width, this.depthCameraConfig.Height, this.depthCameraConfig.ImageFormat);
            }
            else
            {
                this.depthFaceTrackingImage.Attach(
                    this.depthCameraConfig.Width,
                    this.depthCameraConfig.Height,
                    depthImagePtr,
                    this.depthCameraConfig.ImageFormat,
                    this.depthCameraConfig.Stride);
            }
        }