コード例 #1
0
ファイル: Filter.cs プロジェクト: kinectproject/kinectproject
    // AA: Interface function for filtering of individual joints
    public Vector3 Update(Vector3 jointPos, JOINT_TYPE jointType )
    {
        Vector3 newJointPos = Vector3.zero;

        switch (jointType) {

        case JOINT_TYPE.JOINT:
            // Loop arond the joint history buffers if necessary
            if(jointIndex > numHistory - 1)
                jointIndex = jointIndex % numHistory;

            jointHistory[jointIndex] = jointPos;
            newJointPos = applyFilter(jointHistory, jointType);
            jointHistory[jointIndex] = newJointPos;
            jointIndex++;
            break;

        case JOINT_TYPE.RELATIVEJOINT:
            // Loop arond the joint history buffers if necessary
            if(relativeJointIndex > numHistory - 1)
                relativeJointIndex = relativeJointIndex % numHistory;

            // Store joint in history
            relativeJointHistory[relativeJointIndex] = jointPos;
            newJointPos = applyFilter(relativeJointHistory, jointType);
            relativeJointHistory[relativeJointIndex] = newJointPos;
            relativeJointIndex++;

            break;
        default:
        break;

        }

        return newJointPos;
    }
コード例 #2
0
    private Vector3 applyFilter(Vector3 [] array, int arrIndex, JOINT_TYPE jointType, Vector3 [] arrayOutput = null, Filter.FILTER_NAME fname = Filter.FILTER_NAME.NONE)
    {
        Vector3 sum = Vector3.zero;

        switch (fname)
        {
        // Simplest joint filter, where the filter output is the average of N recent inputs
        case FILTER_NAME.SIMPLE_AVG:

            for (int i = 0; i < numHistory; i++)
            {
                sum = sum + array[i];
            }
            sum /= numHistory;
            break;

        // Moving average (MA) filters are a special case of ARMA filters where the auto regressive term is zero
        case FILTER_NAME.MOVING_AVG:

            for (int i = 0; i < numHistory; i++)
            {
                sum = sum + array[i] * weights[i];
            }
            break;

        // Double moving average with window size = 2 (for fast implementation)
        case FILTER_NAME.DOUBLE_MOVING_AVG:
            sum = (5.0f / 9) * array[getIndex(arrIndex)] +
                  (4.0f / 9) * array[getIndex(arrIndex - 1)] +
                  (1.0f / 3) * array[getIndex(arrIndex - 2)] -
                  (2.0f / 9) * array[getIndex(arrIndex - 3)] -
                  (1.0f / 9) * array[getIndex(arrIndex - 4)];
            break;

        // Exponential Smoothing with window size = 2 (for fast implementation)
        case FILTER_NAME.EXP_SMOOTHING:
// The dynamic code works very slowly:
//			for (int i = 0; i < windowSize; i++) {
//				sum += Mathf.Pow((1-alpha), i )*array[getIndex(arrIndex - i)];
//			}
//			sum = alpha*sum;

            // The unrolled loop for window size of two code:
            sum = alpha * array[getIndex(arrIndex)] + (1 - alpha) * array[getIndex(arrIndex - 1)] + (1 - alpha) * (1 - alpha) * array[getIndex(arrIndex - 2)];
            break;

        // Double Exponential Smoothing with window size = 2 (for fast implementation)
        case FILTER_NAME.DOUBLE_EXP_SMOOTHING:
            if (jointType == JOINT_TYPE.JOINT)
            {
                Vector3 trend = gamma * (arrayOutput[getIndex(jointOutputIndex - 1)] - arrayOutput[getIndex(jointOutputIndex - 2)]) + (1 - gamma) * (gamma * (arrayOutput[getIndex(jointOutputIndex - 3)] - arrayOutput[getIndex(jointOutputIndex - 4)]));
                sum = alpha * array[getIndex(arrIndex)] + (1 - alpha) * (arrayOutput[getIndex(arrIndex - 2)] + trend);
            }
            else
            {
                Vector3 trend = gamma * (arrayOutput[getIndex(relativeJointOutputIndex - 1)] - arrayOutput[getIndex(relativeJointOutputIndex - 2)]) + (1 - gamma) * (gamma * (arrayOutput[getIndex(relativeJointOutputIndex - 3)] - arrayOutput[getIndex(relativeJointOutputIndex - 4)]));
                sum = alpha * array[getIndex(arrIndex)] + (1 - alpha) * (arrayOutput[getIndex(arrIndex - 2)] + trend);
            }

            break;

        // Median filter
        case FILTER_NAME.MEDIAN:
            if (jointType == JOINT_TYPE.JOINT)
            {
                sum = findMedian(jointsMedian, array, arrIndex);
            }
            else if (jointType == JOINT_TYPE.RELATIVEJOINT)
            {
                sum = findMedian(relativeJointsMedian, array, arrIndex);
            }

            break;

        // Hand joint filtered by simple avg, shoulder joint by median
        case FILTER_NAME.COMBINATION1:
            if (jointType == JOINT_TYPE.JOINT)
            {
                sum = applyFilter(array, arrIndex, jointType, arrayOutput, Filter.FILTER_NAME.SIMPLE_AVG);
            }
            else if (jointType == JOINT_TYPE.RELATIVEJOINT)
            {
                sum = findMedian(relativeJointsMedian, array, arrIndex);
            }

            break;

        // Hand joint filtered by double moving average, shoulder joint by median
        case FILTER_NAME.COMBINATION2:
            if (jointType == JOINT_TYPE.JOINT)
            {
                sum = applyFilter(array, arrIndex, jointType, arrayOutput, Filter.FILTER_NAME.DOUBLE_MOVING_AVG);
            }
            else if (jointType == JOINT_TYPE.RELATIVEJOINT)
            {
                sum = findMedian(relativeJointsMedian, array, arrIndex);
            }

            break;

        // Jitter removal filter is like a simple case of moving average filter using only current and previous input
        case FILTER_NAME.JITTER_REMOVAL:
            sum = alpha * array[arrIndex] + (1 - alpha) * array[getIndex(arrIndex - 1)];
            break;

        // ADAPTIVE_DOUBLE_EXP_SMOOTHING filter uses a_low and a_high (alpha low and alpha high values)
        case FILTER_NAME.ADAPTIVE_DOUBLE_EXP_SMOOTHING:
            Vector3 diff     = array[arrIndex] - array[getIndex(arrIndex - 1)];
            Vector2 velocity = new Vector2(diff.x, diff.y);

            float vn = velocity.sqrMagnitude;
            if (vn < v_low)
            {
                alpha = a_low;
                gamma = y_low;
            }
            else if (vn > v_high)
            {
                alpha = a_high;
                gamma = y_high;
            }
            else
            {
                alpha = a_high + ((vn - v_high) / (v_low - v_high)) * (a_low - a_high);
                gamma = y_high + ((vn - v_high) / (v_low - v_high)) * (y_low - y_high);
            }

            if (jointType == JOINT_TYPE.JOINT)
            {
                Vector3 myTrend = gamma * (arrayOutput[getIndex(jointOutputIndex - 1)] - arrayOutput[getIndex(jointOutputIndex - 2)]) + (1 - gamma) * (gamma * (arrayOutput[getIndex(jointOutputIndex - 3)] - arrayOutput[getIndex(jointOutputIndex - 4)]));
                sum = alpha * array[getIndex(arrIndex)] + (1 - alpha) * (arrayOutput[getIndex(arrIndex - 2)] + myTrend);
            }
            else
            {
                Vector3 myTrend = gamma * (arrayOutput[getIndex(relativeJointOutputIndex - 1)] - arrayOutput[getIndex(relativeJointOutputIndex - 2)]) + (1 - gamma) * (gamma * (arrayOutput[getIndex(relativeJointOutputIndex - 3)] - arrayOutput[getIndex(relativeJointOutputIndex - 4)]));
                sum = alpha * array[getIndex(arrIndex)] + (1 - alpha) * (arrayOutput[getIndex(arrIndex - 2)] + myTrend);
            }
            break;
        // Taylor series can forecast 1 data point
//		case FILTER_NAME.TAYLOR_SERIES:
//			if(useSmoothedInput)
//			{
//				// Populate the smoothed inputs array for joint/relative joint
//				Vector2 newJointPos = applyFilter(array, arrIndex, jointType, arrayOutput, FILTER_NAME.SIMPLE_AVG);
//
//				sum = array[arrIndex] - 3*array[getIndex(arrIndex-1)] + 3*array[getIndex(arrIndex-2)] - array[getIndex(arrIndex-3)];
//
//				if(jointType == JOINT_TYPE.JOINT)
//				{
//					TS_SmoothInputsJ[jointOutputIndex] = newJointPos;
//					sum = (8.0f/3)*TS_SmoothInputsJ[arrIndex] - (5.0f/2)* TS_SmoothInputsJ[getIndex(arrIndex-1)] + TS_SmoothInputsJ[getIndex(arrIndex-2)] - (1.0f/6)*TS_SmoothInputsJ[getIndex(arrIndex-3)];
//				}
//				else
//				{
//					TS_SmoothInputsRJ[relativeJointOutputIndex] = newJointPos;
//					sum = (8.0f/3)*TS_SmoothInputsRJ[arrIndex] - (5.0f/2)* TS_SmoothInputsRJ[getIndex(arrIndex-1)] + TS_SmoothInputsRJ[getIndex(arrIndex-2)] - (1.0f/6)*TS_SmoothInputsRJ[getIndex(arrIndex-3)];
//
//				}
//
//
//			}

        default:
            break;
        }

        return(sum);
    }
コード例 #3
0
    // AA: Interface function for filtering of individual joints
    public Vector3 Update(Vector3 jointPos, JOINT_TYPE jointType)
    {
        Vector3 newJointPos = Vector3.zero;

        if (name == FILTER_NAME.NONE)
        {
            return(jointPos);
        }

        switch (jointType)
        {
        case JOINT_TYPE.JOINT:
            // Loop arond the joint history buffers if necessary
            if (jointIndex > numHistory - 1)
            {
                jointIndex = jointIndex % numHistory;
            }

            if (jointOutputIndex > numHistory - 1)
            {
                jointOutputIndex = jointOutputIndex % numHistory;
            }


            // Store input in joint's history
            jointHistory[jointIndex] = jointPos;
            newJointPos = applyFilter(jointHistory, jointIndex, jointType, jointOutputs, name);

            jointIndex++;

            // Store the filter output value in the joint's history
            jointOutputs[jointOutputIndex] = newJointPos;
            jointOutputIndex++;
            break;

        case JOINT_TYPE.RELATIVEJOINT:
            // Loop arond the joint history buffers if necessary
            if (relativeJointIndex > numHistory - 1)
            {
                relativeJointIndex = relativeJointIndex % numHistory;
            }

            if (relativeJointOutputIndex > numHistory - 1)
            {
                relativeJointOutputIndex = relativeJointOutputIndex % numHistory;
            }

            // Store input in joint's history
            relativeJointHistory[relativeJointIndex] = jointPos;
            newJointPos = applyFilter(relativeJointHistory, relativeJointIndex, jointType, relativeJointOutputs, name);

            relativeJointIndex++;

            // Store the filter output value in the joint's history
            relativeJointOutputs[relativeJointOutputIndex] = newJointPos;
            relativeJointOutputIndex++;

            break;

        default:
            break;
        }

        return(newJointPos);
    }
コード例 #4
0
ファイル: Filter.cs プロジェクト: kinectproject/kinectproject
    private Vector3 applyFilter(Vector3 [] array, JOINT_TYPE jointType)
    {
        Vector3 sum = Vector3.zero;
        for (int i = 0; i < numHistory; i++) {
            sum = sum + array[i]*weights[i];
        }

        return sum;
    }