1. 程式人生 > >3D手勢識別(二)左右、上下滑動判斷

3D手勢識別(二)左右、上下滑動判斷

場景:前裝攝像頭。

檢測目標:檢測手左右滑動狀態,手沿x方向滑動,z軸為深度方向,y、z方向相對穩定。

                    手上下滑動類似。

步驟:

一、影象識別檢測手,左右滑取最上點/上下滑取得手的最前點;

二、資料處理:中值濾波、平滑處理和卡爾曼濾波;

三、判斷x方向角速度/速度是否超過閾值範圍,檢測移動方向;

四、判斷y方向移動速度是否超過閾值。

部分演算法如下:

檢測某方向速度是否超過閾值範圍,判斷移動方向

/************************************
 Description: 用時間1的位置1與時間0的位置0得到速度與閾值比較
 Method:    CheckLeftRight
 FullName:  CheckLeftRight
 Access:    private
 Parameter: 時間1:const TimeStamp &t1
 Parameter: 位置1:float f1
 Parameter: 時間0:const TimeStamp &t0
 Parameter: 位置0:float f0
 Parameter: 速度閾值:thresh
 Parameter: 標籤名:輸出日誌用 const std::string &label_name
 Returns:   int 0表示小於閾值,1/-1表示方向
 Author:    
 Date:      2018/08/30
 History:
************************************/
int CheckLeftRight(const TimeStamp &t1, float f1, const TimeStamp &t0,
                                            float f0, float thresh, const std::string &label_name) {
        float vt = ComputeVelocity(t1, f1, t0, f0);      
        int sliding_state = CheckVelocity(vt, -thresh, thresh);      
        return sliding_state;
    }
//計算速度
float ComputeVelocity(const TimeStamp &t1, float f1, const TimeStamp &t0, float f0) {
    double dt = (t1 - t0).toSec();
    double delta_f = f1 - f0;
    double v = delta_f / dt;
    return static_cast<float>(v);
}
//判斷
int CheckVelocity(double v, float thresh_low, float thresh_high) {
    if (v > thresh_high) {
        return 1;
    }
    if (v < thresh_low) {
        return -1;
    }
    return 0;
}