计算手部追踪原始数据的平均值
Calculating the average of raw data for hand tracking
我一直在尝试计算从相机接收到的原始数据的平均值。原因是目前我只使用原始数据,这会导致相当大的抖动。因此,我想要过去 5 个位置,然后计算平均值,因为这将使手部跟踪体验更加流畅。
我一直在尝试存储前 5 个位置,但是当我尝试这样做时,我只获得了最新的原始数据,然后将其存储并覆盖这些位置。
OnNewFrame() 方法是我获取原始数据的地方。
帮助我如何做到这一点会很棒。
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();
}
}
}
你能为每个 xpos、ypos、zpos 和一个 indexAverage 添加一个 5 double 的数组吗
将它们全部设为私有 class 变量
在你的新框架函数中使用:
Xpos_array [indexAverage]= (screenWidth - (nData.positionImage.x * xRatio)) + (screenWidth / 2);
Xpos = Xpos_array.select(x => x / 5.0).sum();
[.......]
indexAverage = (indexAverage+1)%5;
我一直在尝试计算从相机接收到的原始数据的平均值。原因是目前我只使用原始数据,这会导致相当大的抖动。因此,我想要过去 5 个位置,然后计算平均值,因为这将使手部跟踪体验更加流畅。
我一直在尝试存储前 5 个位置,但是当我尝试这样做时,我只获得了最新的原始数据,然后将其存储并覆盖这些位置。
OnNewFrame() 方法是我获取原始数据的地方。
帮助我如何做到这一点会很棒。
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();
}
}
}
你能为每个 xpos、ypos、zpos 和一个 indexAverage 添加一个 5 double 的数组吗
将它们全部设为私有 class 变量
在你的新框架函数中使用:
Xpos_array [indexAverage]= (screenWidth - (nData.positionImage.x * xRatio)) + (screenWidth / 2);
Xpos = Xpos_array.select(x => x / 5.0).sum();
[.......]
indexAverage = (indexAverage+1)%5;