vaguely

和歌山に戻りました。ふらふらと色々なものに手を出す毎日。

iOSでOpenCV

開発環境が落ち着かない感じですが、OpenCV for iOSを使って、画像をいじってみたお話。

Install

  1. 公式サイトのDOWNLOADSからOpenCV for iOS(ver. 2.4.9)をダウンロードして、任意の場所に展開する(opencv2.framework)
  2. Xcodeで新規プロジェクトを作成する
  3. プロジェクトエディタ>Build Phases>Link Binary With Librariesに、Step1のFrameworkを追加する

準備

  1. OpenCVを使用するファイルの拡張子を.mmに変更してC++のコードが使用できるようにする
  2. "opencv2/opencv.hpp", "opencv2/highgui/ios.h"をインポートする

画像の変換

流れは以下のような感じ。

  1. [UIImageToMat]を使用してUIImageからcv::Matに変換して画像を操作
  2. [MatToUIImage]を使用してcv::MatからUIImageに変換
  3. UIImageViewに画像を設定して表示

ViewController.mm


#import "ViewController.h"
#import 
#import "opencv2/highgui/ios.h"

@interface ViewController ()
@property (weak, nonatomic) IBOutlet UIImageView *imvView;
@property (strong, nonatomic) UIImage *imgCurrent;
@property (strong, nonatomic) UIImage *imgColor;
@property (strong, nonatomic) UIImage *imgGray;
@property (strong, nonatomic) UIImage *imgThreshold;
@property (strong, nonatomic) UIImage *imgSobel;
@end
@implementation ViewController
            
- (void)viewDidLoad {
    [super viewDidLoad];
    
    NSString *strImageURL = @"https://joindiaspora.s3.amazonaws.com/uploads/images/scaled_full_1081a16e63283b49bfab.jpg";
    
    _imgColor = [UIImage imageWithData:[NSData dataWithContentsOfURL: [NSURL URLWithString: strImageURL]]];
    
    cv::Mat matColor;
    
    // UIImageをcv::Matに変換する
    UIImageToMat(_imgColor, matColor);
    
    // グレイスケール
    cv::Mat matGray;
    cv::cvtColor(matColor, matGray, CV_BGR2GRAY);
    // cv::MatをUIImageに変換
    _imgGray = MatToUIImage(matGray);
    
    // 白黒の2値化処理
    cv::Mat matThreshold;
    cv::threshold(matGray, matThreshold, 0, 255, cv::THRESH_BINARY|cv::THRESH_OTSU);
    // cv::MatをUIImageに変換
    _imgThreshold = MatToUIImage(matThreshold);
    
    // Sobelフィルタによる輪郭検出
    cv::Mat matSobel;
    cv::Sobel(matThreshold, matSobel, CV_16S, 1, 0, 3);
    cv::convertScaleAbs(matSobel, matSobel);
    // cv::MatをUIImageに変換
    _imgSobel = MatToUIImage(matSobel);
    
    _imgCurrent = _imgColor;
    [self setCurrentImgView];
}

あとは適当にボタンを追加して、ボタンを押したら「imvView.image = imgColor;」のようにUIImageViewに好きなUIImageをセットしてやればOKです。

ViewController.mm

- (IBAction)btnColorTouched:(id)sender {
  _imgColor = _imgCurrent;
    // ImageViewに画像をセット
    _imvView.image = _imgCurrent;
}

参考

保存

せっかくなので、変換した画像を保存してみます。

- (IBAction)btnSaveTouched:(id)sender {
    //画像を保存する
    UIImageWriteToSavedPhotosAlbum(_imgCurrent, self, NULL, NULL);
}

処理が完了したときに何かを実行したい場合、[UIImageWriteToSavedPhotosAlbum]の3つ目の引数にセレクタを設定してやれば良いようです。

参考


次は画像認識に挑戦したいところですが、Alpha版ながらver.3.0がダウンロード可能になっているし、Swiftも触ってみたいし...。

誘惑は多いですが、いろいろ寄り道しつつ試していきたいと思います。