(注意) 追加したframework が認識されない場合は、プロジェクトの "Build Settings" -> "Search Paths" -> "Framework Search Paths" の "Debug" と "Release" の両方に opencv2.framework が存在するパスを付け加えましょう。(例では /Users/nitta/doc/iApp/2016 )
iOS -> Cocoa Touch Class -> Next を選ぶとクラス名の入力になります。ここではクラス名は ObjCWrapper、Subclass ofに NSObject, LauguageにObjective-C を選択しました。
このあと「SwiftとObjective-Cをブリッジ(橋渡し)するHeaderを作るか」と確認を求められるので "Create Bridging Header" を選択します。 ブリッジングヘッダーファイルの名前は「プロジェクト名-Bridging-Header.h」となります。
ObjCWrapper.h, ObjCWrapper.m, SwiftOpenCV-Bridging-Header.h が新たに生成されました。
SwiftOpenCV-Bridging-Header.hに追加するコード(赤字部分) |
#import "ObjCWrapper.h" |
ObjCWrapper.hに追加するコード(赤字部分) |
#import <Foundation/Foundation.h> #import <UIKit/UIKit.h> @interface ObjCWrapper : NSObject - (bool) isActive; - (bool) setXML: (NSString *) name; - (int) detect: (UIImage *) image founds: (NSMutableArray *) arr; @end |
ObjCWrapper.mmに追加するコード(赤字部分) |
#import "ObjCWrapper.h" #import <opencv2/opencv.hpp> #import <opencv2/highgui/ios.h> using namespace std; @implementation ObjCWrapper cv::CascadeClassifier cascade; bool active; - (bool) isActive { return active; } - (bool) setXML: (NSString *) name { NSBundle *bundle = [NSBundle mainBundle]; NSString *path = [bundle pathForResource: name ofType:@"xml"]; string cascadeName = (char *) [path UTF8String]; if (!cascade.load(cascadeName)) { return active = false; } return active = true; } - (int) detect: (UIImage *) image founds: (NSMutableArray *) arr { CGColorSpaceRef colorSpace = CGImageGetColorSpace(image.CGImage); CGFloat cols = image.size.width; CGFloat rows = image.size.height; cv::Mat mat(rows,cols,CV_8UC4); CGContextRef contextRef = CGBitmapContextCreate(mat.data, cols, rows, 8, mat.step[0], colorSpace, kCGImageAlphaNoneSkipLast); CGContextDrawImage(contextRef, CGRectMake(0, 0, cols, rows), image.CGImage); CGContextRelease(contextRef); vector<cv::Rect> founds; cascade.detectMultiScale(mat, founds, 1.1, 2, CV_HAAR_SCALE_IMAGE,cv::Size(30,30)); for (int i=0; i<founds.size(); i++) { cv::Rect rect = founds[i]; [arr addObject: [NSNumber numberWithInteger: rect.x]]; [arr addObject: [NSNumber numberWithInteger: rect.y]]; [arr addObject: [NSNumber numberWithInteger: rect.width]]; [arr addObject: [NSNumber numberWithInteger: rect.height]]; } return (int) [arr count]; } @end |
ViewController.swiftに追加するコード(赤字部分) |
import UIKit class ViewController: UIViewController { var detector: ObjCWrapper! @IBOutlet weak var myImageView: UIImageView! @IBAction func tapButton(sender: AnyObject) { let image: UIImage? = UIImage(named: "lena.jpg") myImageView.image = image; if (detector.isActive()) { let arr = NSMutableArray() detector.detect(image,founds: arr) print(arr.count) UIGraphicsBeginImageContext(image!.size); image!.drawInRect(CGRectMake(0,0,image!.size.width,image!.size.height)) let context: CGContextRef = UIGraphicsGetCurrentContext()! CGContextSetRGBStrokeColor(context, 1.0, 0.0, 0.0, 1.0) CGContextSetLineWidth(context, 5.0); for i in 0..<(arr.count/4) { let x:Int = arr[i * 4 + 0] as! NSNumber as Int let y:Int = arr[i * 4 + 1] as! NSNumber as Int let w:Int = arr[i * 4 + 2] as! NSNumber as Int let h:Int = arr[i * 4 + 3] as! NSNumber as Int print("\(i): \(x) \(y) \(w) \(h)") CGContextAddRect(context, CGRectMake(CGFloat(x),CGFloat(y),CGFloat(w),CGFloat(h))); } CGContextStrokePath(context) let img = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() myImageView.image = img; } } override func viewDidLoad() { super.viewDidLoad() detector = ObjCWrapper(); detector.setXML("haarcascade_frontalface_alt") } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() } } |
ウィンドウ左のProject Navigator でプロジェクトを選択して、マウスの右クリックで "Add Files to プロジェクト名"を選択します。 ファイル選択の画面ではまず Option をクリックして "Copy items if needed" にチェックをいれてから、Addします。
ウィンドウ左のProject Navigator でプロジェクトを選択して、マウスの右クリックで "Add Files to プロジェクト名"を選択します。 ファイル選択の画面ではまず Option をクリックして "Copy items if needed" にチェックをいれてから、Addします。
--> |