





(注意) 追加した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します。




| --> |
|