[Xcode4,Objective-C++] OpenCV2.4.1をiOSで使う

画像認識や画像処理をするのに大変便利なオープンソースのライブラリOpenCVをiPhoneやiPadでも使えるようにするためのメモ。もっとスマートなやり方があると思うので、ご存知の方はコメント欄で教えてください。

OpenCVのコンパイル

  1. OpenCVのWebサイトからOpenCVのrelease versionをダウンロードする
  2. OpenCVを導入したいプロジェクトの.xcodeprojファイルと同じディレクトリにダウンロードしたファイルを解凍する。
  3. OpenCVのディレクトリ名を「opencv」に変更する
  4. ターミナルを起動し、プロジェクト名と同じ名前のディレクトリへcd(change directory)する(以下の画像のように「cd 」と途中まで入力してからディレクトリをドラッグ&ドロップすると楽にフルパスが入力できる)
  5. 以下を順に実行する(とても時間がかかる)
    $ ../opencv/ios/configure-device_xcode.sh
    $ xcodebuild -sdk iphoneos -configuration Release -target ALL_BUILD
    $ xcodebuild -sdk iphoneos -configuration Release -target install install
    
  6. 「OpenCV_iPhoneOS」というディレクトリが生成されているのを確認する

Xcodeプロジェクトの設定

  1. 「Header Search Paths」に以下を追加。チェックボックス(Recursive)をONにする
    ./OpenCV_iPhoneOS/include/
    

  2. ファイル「(プロジェクト名)/OpenCV.xcodeproj」をプロジェクトに追加する
  3. ターゲットの「Build Phases」タブにある「Link Binary With Libraries」の+をクリックして必要なファイルを追加する。
  4. Supporting Filesの中の「(プロジェクト名)-Prefix.pch」の中を以下のように書き換える
    #import <Availability.h>
    
    #ifndef __IPHONE_4_0
    #warning "This project uses features only available in iOS SDK 4.0 and later."
    #endif
    
    /* ここから追加 */
    #ifdef __cplusplus
    	#import <opencv2/opencv.hpp>
    #endif
    /* ここまで追加 */
    
    #ifdef __OBJC__
    	#import <UIKit/UIKit.h>
    	#import <Foundation/Foundation.h>
    #endif
    
  5. コンパイルする(コンパイルできることを確認する)

実際に使ってみる

UIViewControllerのメソッドファイルの拡張子「.m」を「.mm」に変更してから以下のように変更した。(.mmへ変更することでObjective-C++を使う)

- (void)viewDidLoad {
    [super viewDidLoad];
	
	// cv::Matを生成
	cv::Mat srcImg(cv::Size(480,640), CV_8UC3);
	
	// グラデーションで塗りつぶす
	for( int y = 0; y < srcImg.rows; y++ ) {
		cv::Vec3b* ptr = srcImg.ptr<cv::Vec3b>( y );
		for( int x = 0; x < srcImg.cols; x++ ) {
			cv::Vec3b bgr = ptr[x];
			ptr[x] = cv::Vec3b(1.0 * x / srcImg.cols * 255, 0, 0);
		}
	}
	
	// UIImageViewに表示する
	UIImage *image = [self UIImageFromMat:srcImg];
	UIImageView *imgView = [[[UIImageView alloc] initWithImage:image] autorelease];
	[self.view addSubview:imgView];
}

/*
 参考: http://www.patokeefe.com/archives/721
 */
- (UIImage *)UIImageFromMat:(cv::Mat)image {
    NSData *data = [NSData dataWithBytes:image.data length:image.elemSize()*image.total()];
	
    CGColorSpaceRef colorSpace;
	
    if (image.elemSize() == 1) {
        colorSpace = CGColorSpaceCreateDeviceGray();
    } else {
        colorSpace = CGColorSpaceCreateDeviceRGB();
    }
	
    CGDataProviderRef provider = CGDataProviderCreateWithCFData((__bridge CFDataRef)data);
	
    // Creating CGImage from cv::Mat
    CGImageRef imageRef = CGImageCreate(image.cols, image.rows,
                                        8, 8 * image.elemSize(),
                                        image.step.p[0], colorSpace,
										kCGImageAlphaNone|kCGBitmapByteOrderDefault,
                                        provider, NULL, false,
                                        kCGRenderingIntentDefault);
	
    // Getting UIImage from CGImage
    UIImage *finalImage = [UIImage imageWithCGImage:imageRef];
    CGImageRelease(imageRef);
    CGDataProviderRelease(provider);
    CGColorSpaceRelease(colorSpace);
	
    return finalImage;
}

下図のように、グラデーションが表示された。

参考文献

追記

以下のブログ記事に、追加情報がありました。


「[Xcode4,Objective-C++] OpenCV2.4.1をiOSで使う」への2件のフィードバック

コメントを残す