user3599078
user3599078

Reputation: 3

Calculating the average of raw data for hand tracking

I have been trying to calculate the average of the raw data that I have been receiving from my camera. The reason is that at the moment I am just using the raw data and this causes quite abit of jitter. Therefore I am wanting the past 5 locations and then an average to be calculated as this would make the hand tracking experience much more smoother.

I have been trying to store the previous 5 locations but when I attempted this I only get the latest raw data which then get stored and overwrites it for the locations.

The OnNewFrame() method is where I get the raw data.

Help on how I would do this would great.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;
using SDKAttempt;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using System.Drawing;
//The sdk module tracks geometric  nodes for every frame


  namespace PercUtils
  {
    class DepthPipeline : UtilMPipeline
    {
        double screenWidth = GraphicsAdapter.DefaultAdapter.CurrentDisplayMode.Width;
        double screenHeight = GraphicsAdapter.DefaultAdapter.CurrentDisplayMode.Height;
        PXCMGesture.GeoNode nData; //data the we will get from the camera

        double xPos = 0;
        double yPos = 0;
        double zPos = 0;
        double handOpeness = 0;
        private bool finished;
        PXCMGesture.GeoNode[] nodeData = new PXCMGesture.GeoNode[1]; //data from hand


        public DepthPipeline()
            : base()
        {
            finished = false;
            EnableImage(PXCMImage.ColorFormat.COLOR_FORMAT_DEPTH);
            EnableGesture(); //This function is called to enable finger tracking and gesture recognition
        }


        public override void OnGestureSetup(ref PXCMGesture.ProfileInfo pinfo) //the application can override this function to fine-tune any parameters during module  initilisation
        {
            base.OnGestureSetup(ref pinfo);
        }
        public override void OnGesture(ref PXCMGesture.Gesture gesture) //the application needs to receive pose/gesture, the application can override the ongesture function
        {
            if (gesture.label == PXCMGesture.Gesture.Label.LABEL_POSE_THUMB_UP)
            {
                Console.WriteLine("Thumb Up"); //debug
            }

            base.OnGesture(ref gesture);
        }
        public override void OnAlert(ref PXCMGesture.Alert alert) //the application can override the OnAlert function to receive alert notifications
        {

            base.OnAlert(ref alert);
        }

        public override bool OnNewFrame()
        {
            double xRatio = screenWidth / 160;  //corrects the ratio of the x axis of the camera to work with the width screen - scales the camera cood for the screen being used
            double yRatio = screenHeight / 120; //corrects the ratio of the y axis of the camera to work with the height screen - scales the camera cood for the screen being used 
            PXCMGesture gesture = QueryGesture();
            pxcmStatus sts = gesture.QueryNodeData(0, PXCMGesture.GeoNode.Label.LABEL_BODY_HAND_LEFT, out nData); //gets the status of the left hand, out nData because the value isn't set and the function must set it before returning it



            if (sts >= pxcmStatus.PXCM_STATUS_NO_ERROR)
            {

                xPos = (screenWidth - (nData.positionImage.x * xRatio)) + (screenWidth / 2);
                yPos = ((nData.positionImage.y * yRatio) - (screenHeight / 2));
                zPos = nData.positionWorld.y * 100;
                handOpeness = nData.openness;

                TitleScreen.setX(xPos); //this corrects the inverted control of the dot
                TitleScreen.setY(yPos);
                TitleScreen.getHandOpenness(handOpeness);

                PlayGame.setX(xPos); //this corrects the inverted control of the dot
                PlayGame.setY(yPos);
                PlayGame.getHandOpeness(handOpeness);
                PlayGame.getZ(zPos); //gets the z coordnidate of the users hand.

                PlayGameEasy.setX(xPos); //this corrects the inverted control of the dot
                PlayGameEasy.setY(yPos);
                PlayGameEasy.getHandOpeness(handOpeness);
                PlayGameEasy.getZ(zPos); //gets the z coordnidate of the users hand.

                CollisionClass.setX(xPos);
                CollisionClass.setY(yPos);
                CollisionClass.getZ(zPos);

                Button.setX(xPos);
                Button.setY(yPos);
                Button.getHandOpeness(handOpeness);

                ReplayScreen.getX(xPos);
                ReplayScreen.getY(yPos);

                HighScore.getX(xPos);
                HighScore.getY(yPos);

                DifficultyScreen.getX(xPos);
                DifficultyScreen.getY(yPos);
            }
            return !finished;

        }

        public void Finish()
        {
            finished = true;
        }

        public bool IsFinished()
        {
            return finished;
        }

        public void StartWork()
        {
            finished = false;
            this.LoopFrames();
        }

    }
}

Upvotes: 0

Views: 113

Answers (1)

PandaBlue
PandaBlue

Reputation: 361

Could you add an array of 5 double for each xpos, ypos, zpos and an indexAverage

Make all of them private class variables

In your new frame function use:

  Xpos_array [indexAverage]= (screenWidth - (nData.positionImage.x * xRatio)) + (screenWidth / 2);

 Xpos = Xpos_array.select(x => x / 5.0).sum();

[.....]

  indexAverage = (indexAverage+1)%5;

Upvotes: 0

Related Questions