iOS+OpenCV: OpenCV iOS - Video Processing

[OpenCV iOS - Video Processing](http://docs.opencv.org/doc/tutorials/ios/video_processing/video_processing.html)を実際に動かしてみました。

# Including OpenCV library in your iOS project
* プロジェクトを新規作成
 * storyboardは使ったことがないのでEmpty Applicationで作成。
* opencv2.frameworkの組み込み。
* -Prefix.pchにopencv.hppを追加。

## Example video frame processing project

### User Interface
* ViewControllerを新規作成してカメラ用のImageViewとボタンを載せる。
 * 拡張子は.mmにする。
 * ボタンはStart/Stopのトグルにする。
* Portraitのみ対応。
 * 設定（General - Deployment Info）の`Landscape Left`と`Landscape Right`のチェックを外す。

```objc:AppDelegate.m
#import "ViewController.h"

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    // Override point for customization after application launch.
    self.window.backgroundColor = [UIColor whiteColor];
    self.window.rootViewController = [[ViewController alloc] init];
    [self.window makeKeyAndVisible];
    return YES;
}
```

```objc:ViewController.mm
@interface ViewController ()
{
  BOOL shooting;
  UIButton *button;
}
@end

- (void)pushButton
{
  NSString *str;
  if( shooting )
  {
    str = @"Start";
  }
  else
  {
    str = @"Stop";
  }
  [button setTitle:str forState:UIControlStateNormal];
  shooting = !shooting;
}

- (void)viewDidLoad
{
  //camera view
  UIImageView *camera = [[UIImageView alloc] initWithFrame:self.view.frame];
  [self.view addSubview:camera];
  
  //button
  CGFloat sw = self.view.frame.size.width;
  CGFloat sh = self.view.frame.size.height;
  CGFloat w = sw/2;
  CGFloat h = w/3;
  button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
  button.frame = CGRectMake( (sw-w)/2, sh-h-h/2, w, h );
  [button addTarget:self action:@selector(pushButton) forControlEvents:UIControlEventTouchUpInside];
  button.backgroundColor = [UIColor orangeColor];
  [self.view addSubview:button];
  
  //initial
  shooting = !NO;
  [self pushButton];
}
```

### Adding the Camera
* CvVideoCameraのメンバ`grayscale`は`grayscaleMode`に名前が変わってた。(2.4.9)
* フレームワークを追加。

```objc:ViewController.mm
@interface ViewController ()
{
  CvVideoCamera *videoCamera;
}
@end

- (void)viewDidLoad
{
  //camera
  videoCamera = [[CvVideoCamera alloc] initWithParentView:camera];
  videoCamera.defaultAVCaptureDevicePosition = AVCaptureDevicePositionFront;
  videoCamera.defaultAVCaptureSessionPreset = AVCaptureSessionPresetHigh;
  videoCamera.defaultAVCaptureVideoOrientation = AVCaptureVideoOrientationPortrait;
  videoCamera.defaultFPS = 30;
  videoCamera.grayscaleMode = NO;
}
```

### Processing frames
* Delegateを追加。

```objc:ViewController.mm
@interface ViewController () <CvVideoCameraDelegate>

#ifdef __cplusplus
- (void)processImage:(cv::Mat &)image
{
}
#endif

- (void)viewDidLoad
{
  videoCamera.delegate = self;
}
```

### Basic video processing
```objc:ViewController.mm
- (void)processImage:(cv::Mat &)image
{
  cv::Mat image_copy;
  cv::cvtColor( image, image_copy, CV_BGRA2BGR );
  
  //invert
  cv::bitwise_not( image_copy, image_copy );
  cv::cvtColor( image_copy, image, CV_BGR2BGRA );
}
```

### Start! (and Stop)
```objc:ViewController.mm
- (void)pushButton
{
  if( shooting )
  {
    [videoCamera stop];
  }
  else
  {
    [videoCamera start];
  }
}
```

### ~~Hints~~ Problems
* ~~Start/Stopを繰り返すと猛烈にメモリリークする。~~
 * リークはしてないっぽい。Start時に異常なサイズのメモリを確保している模様。
* 横を向けた状態でStartするとカメラが横を向いている。