評価環境
- xcode5
- opencv 2.4.9
opencv のダウンロード
http://opencv.org/downloads.html
以下から framework をダウンロードします。
framework を利用すると非常に簡単に組み込めます。
その一方、framework作成時のコンパイラ設定とプロジェクトのコンパイラ設定が異なるとビルドできないこともあります。
自分でビルドすれば、コンパイラの設定違いに悩まされることはないです。
少なくともこの記事の記載時点では、特にプロジェクトのデフォルトの設定から変える必要はありません。
xcode でプロジェクトから参照する
プロジェクトでフレームワークを追加します。
先ほどダウンロードしたフレームワークを指定します。
ソースを .mm にする
opencv の c++ ライブラリを使うので、ソースを .mm にします。
これで objective-c と c++ の混在ができます。
ヘッダをインポートします
// .mm ファイル
// opencv の import
#import <opencv2/opencv.hpp>
#import <opencv2/highgui/ios.h>
opencv を使う
iOS では一般的に UIImage 型を利用します。
一方 opencv では cv::Mat 型を利用します。
そのため、iOS 上での一般的な処理の流れは以下のようになります。
- UIImage を cv::Mat に変換する。
- opencv API を利用します。
- cv::Mat を UIImage に変換して、表示などに利用。
UIImage を cv::Mat にする
UIImageToMat を用います。
変換のために以下のような変換メソッドを用意します。
- (cv::Mat)matWithImage:(UIImage*)image
{
// 画像の回転を補正する(内蔵カメラで撮影した画像などでおかしな方向にならないようにする)
UIImage* correctImage = image;
UIGraphicsBeginImageContext(correctImage.size);
[correctImage drawInRect:CGRectMake(0, 0, correctImage.size.width, correctImage.size.height)];
correctImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
// UIImage -> cv::Mat
cv::Mat mat;
UIImageToMat(correctImage, mat);
return mat;
}
cv::Mat を UIImage にする
MatToUIImage を用います。
サンプルコード
//
// ViewController.mm
// opencvSample1
//
//
#import "ViewController.h"
#import <opencv2/opencv.hpp>
#import <opencv2/highgui/ios.h>
@interface ViewController () {
UIImage* _origImage;
}
@end
@implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// ImageView の Outlet として imageView を用意した。
// imageView には予め画像を設定してあるので、ここで元の画像をとっておく。
_origImage = self.imageView.image;
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (cv::Mat)matWithImage:(UIImage*)image
{
// 画像の回転を補正する(内蔵カメラで撮影した画像などでおかしな方向にならないようにする)
UIImage* correctImage = image;
UIGraphicsBeginImageContext(correctImage.size);
[correctImage drawInRect:CGRectMake(0, 0, correctImage.size.width, correctImage.size.height)];
correctImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
// UIImage -> cv::Mat
cv::Mat mat;
UIImageToMat(correctImage, mat);
return mat;
}
- (IBAction)onGray:(id)sender {
cv::Mat mat = [self matWithImage:_origImage];
// グレイスケール化
cv::cvtColor(mat, mat, CV_BGR2GRAY);
// 変換結果を画面に表示
self.imageView.image = MatToUIImage(mat);
}
- (IBAction)onNot:(id)sender {
cv::Mat mat = [self matWithImage:_origImage];
// ネガポジ反転
mat = ~mat;
self.imageView.image = MatToUIImage(mat);
}
- (IBAction)onOtsu:(id)sender {
cv::Mat mat = [self matWithImage:_origImage];
// グレイスケール化してから大津法で二値化
cv::cvtColor(mat, mat, CV_BGR2GRAY);
cv::threshold(mat, mat, 0, 255, cv::THRESH_BINARY|cv::THRESH_OTSU);
self.imageView.image = MatToUIImage(mat);
}
- (IBAction)onAdaptive:(id)sender {
cv::Mat mat = [self matWithImage:_origImage];
// グレイスケール化してから適応的二値化
cv::cvtColor(mat, mat, CV_BGR2GRAY);
cv::adaptiveThreshold(mat, mat, 255, cv::ADAPTIVE_THRESH_GAUSSIAN_C, cv::THRESH_BINARY, 7, 8);
self.imageView.image = MatToUIImage(mat);
}