/* * Copyright 2019 The TensorFlow Authors. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "gesture_predictor.hpp" #include "constants.hpp" namespace { /* State for the averaging algorithm we're using. */ float prediction_history[kGestureCount][kPredictionHistoryLength] = {}; int prediction_history_index = 0; int prediction_suppression_count = 0; } /* namespace */ /* Return the result of the last prediction * 0: wing("W"), 1: ring("O"), 2: slope("angle"), 3: unknown */ int PredictGesture(float *output) { /* Record the latest predictions in our rolling history buffer. */ for (int i = 0; i < kGestureCount; ++i) { prediction_history[i][prediction_history_index] = output[i]; } /* Figure out which slot to put the next predictions into. */ ++prediction_history_index; if (prediction_history_index >= kPredictionHistoryLength) { prediction_history_index = 0; } /* Average the last n predictions for each gesture, and find which has the * highest score. */ int max_predict_index = -1; float max_predict_score = 0.0f; for (int i = 0; i < kGestureCount; i++) { float prediction_sum = 0.0f; for (int j = 0; j < kPredictionHistoryLength; ++j) { prediction_sum += prediction_history[i][j]; } const float prediction_average = prediction_sum / kPredictionHistoryLength; if ((max_predict_index == -1) || (prediction_average > max_predict_score)) { max_predict_index = i; max_predict_score = prediction_average; } } /* If there's been a recent prediction, don't trigger a new one too soon. */ if (prediction_suppression_count > 0) { --prediction_suppression_count; } /* If we're predicting no gesture, or the average score is too low, or there's * been a gesture recognised too recently, return no gesture. */ if ((max_predict_index == kNoGesture) || (max_predict_score < kDetectionThreshold) || (prediction_suppression_count > 0)) { return kNoGesture; } else { /* Reset the suppression counter so we don't come up with another prediction * too soon. */ prediction_suppression_count = kPredictionSuppressionDuration; return max_predict_index; } }