2013-05-13 95 views
1

我想要創建一個讀取用戶手勢(基於加速度計)並識別它的項目,我搜索了很多,但是我發現的所有內容都太舊了,我在分類和識別時都沒有問題,我將使用1美元識別器或HMM,我只想知道如何使用加速度計讀取用戶的手勢。基於iOS加速度計的手勢識別

加速度計數據(x,y,z值)是否足夠或我應該使用其他數據,如姿態數據(滾動,俯仰,偏航),陀螺儀數據或量級數據,我甚至都不瞭解任何他們這樣解釋這些傳感器做些什麼將是有用的。

在此先感謝!

回答

6

最後我做到了,我用userAcceleration數據這是設備的加速度由於設備不包括重力,我發現有很多人使用正常的加速度數據和做數學的很多,可以移除重力,現在它已經由iOS 6在userAcceleration中完成。

而且我使用了1個識別器,它是一個2D識別器(即點(5,10),無Z)。
這是1$ recognizer的鏈接,在下載部分有一個C++版本。

這裏是我的代碼的步驟...

  1. 閱讀userAcceleration數據與frequancy 50 HZ。
  2. 對其應用低通濾波器。
  3. 僅當其x或y值大於0.05以降低噪音時才考慮這一點。
    (注意:下一步取決於您的代碼和您使用的識別器)。
  4. 將x和y點保存到數組中。
  5. 從這個數組中創建一個2D路徑。
  6. 發送此路徑到識別器進行天氣訓練或識別它。

這裏是我的代碼...

@implementation MainViewController { 
    double previousLowPassFilteredAccelerationX; 
double previousLowPassFilteredAccelerationY; 
double previousLowPassFilteredAccelerationZ; 

    CGPoint position; 
    int numOfTrainedGestures; 
    GeometricRecognizer recognizer; 
} 

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 
// Do any additional setup after loading the view, typically from a nib. 

    previousLowPassFilteredAccelerationX = previousLowPassFilteredAccelerationY = previousLowPassFilteredAccelerationZ = 0.0; 

    recognizer = GeometricRecognizer(); 

    //Note: I let the user train his own gestures, so i start up each time with 0 gestures 
    numOfTrainedGestures = 0; 
} 

#define kLowPassFilteringFactor 0.1 
#define MOVEMENT_HZ 50 
#define NOISE_REDUCTION 0.05 

- (IBAction)StartAccelerometer 
{ 
    CMMotionManager *motionManager = [CMMotionManager SharedMotionManager]; 
    if ([motionManager isDeviceMotionAvailable]) 
    { 
     [motionManager setDeviceMotionUpdateInterval:1.0/MOVEMENT_HZ]; 
     [motionManager startDeviceMotionUpdatesToQueue:[NSOperationQueue currentQueue] 
             withHandler: ^(CMDeviceMotion *motion, NSError *error) 
     { 
      CMAcceleration lowpassFilterAcceleration, userAcceleration = motion.userAcceleration; 

      lowpassFilterAcceleration.x = (userAcceleration.x * kLowPassFilteringFactor) + (previousLowPassFilteredAccelerationX * (1.0 - kLowPassFilteringFactor)); 
      lowpassFilterAcceleration.y = (userAcceleration.y * kLowPassFilteringFactor) + (previousLowPassFilteredAccelerationY * (1.0 - kLowPassFilteringFactor)); 
      lowpassFilterAcceleration.z = (userAcceleration.z * kLowPassFilteringFactor) + (previousLowPassFilteredAccelerationZ * (1.0 - kLowPassFilteringFactor)); 

      if (lowpassFilterAcceleration.x > NOISE_REDUCTION || lowpassFilterAcceleration.y > NOISE_REDUCTION) 
       [self.points addObject:[NSString stringWithFormat:@"%.2f,%.2f", lowpassFilterAcceleration.x, lowpassFilterAcceleration.y]]; 

      previousLowPassFilteredAccelerationX = lowpassFilterAcceleration.x; 
      previousLowPassFilteredAccelerationY = lowpassFilterAcceleration.y; 
      previousLowPassFilteredAccelerationZ = lowpassFilterAcceleration.z; 


      // Just viewing the points to the user 
      self.XLabel.text = [NSString stringWithFormat:@"X : %.2f", lowpassFilterAcceleration.x]; 
      self.YLabel.text = [NSString stringWithFormat:@"Y : %.2f", lowpassFilterAcceleration.y]; 
      self.ZLabel.text = [NSString stringWithFormat:@"Z : %.2f", lowpassFilterAcceleration.z]; 
     }]; 
    } 
    else NSLog(@"DeviceMotion is not available"); 
} 


- (IBAction)StopAccelerometer 
{ 
    [[CMMotionManager SharedMotionManager] stopDeviceMotionUpdates]; 

    // View all the points to the user 
    self.pointsTextView.text = [NSString stringWithFormat:@"%d\n\n%@", self.points.count, [self.points componentsJoinedByString:@"\n"]]; 

    // There must be more that 2 trained gestures because in recognizing, it gets the closest one in distance 
    if (numOfTrainedGestures > 1) { 
     Path2D path = [self createPathFromPoints]; // A method to create a 2D path from pointsArray 
     if (path.size()) { 
      RecognitionResult recongnitionResult = recognizer.recognize(path); 
      self.recognitionLabel.text = [NSString stringWithFormat:@"%s Detected with Prob %.2f !", recongnitionResult.name.c_str(), 
             recongnitionResult.score]; 
     } else self.recognitionLabel.text = @"Not enough points for gesture !"; 
    } 
    else self.recognitionLabel.text = @"Not enough templates !"; 

    [self releaseAllVariables]; 
} 
+0

謝謝你的代碼示例。你使用了哪個cpp庫,你有一個完整的例子嗎?這會非常有幫助。 – 2014-01-31 12:41:43

+0

@Zabady +1回覆。我只有幾個問題。你能否解釋一下我們如何得出lowPassFilter?另外,我得到了所有負面的滾動,偏航和俯仰加速度值。這是正常的嗎?如果是這樣,我們將如何根據這些負值計算加速率?提前致謝。 – Unheilig 2014-02-22 12:02:32

+0

這太棒了!你開發這個產品的是什麼產品? – tadelv 2014-04-21 16:13:48