這個(gè)章節(jié)解釋了使用iPhone的攝像頭和Opencv來進(jìn)行視頻處理。
預(yù)準(zhǔn)備
- Xcode 4.3 或更高
- iOS開發(fā)的基礎(chǔ)知識(shí)(Objective-C, Interface Builder)
導(dǎo)入Opencv庫(kù)到iOS工程
Opencv庫(kù)作為被調(diào)用的框架升薯,你可以直接拖拽到你的工程中岂却。從這里下載最新的庫(kù)重抖⊙鳎或者按照iOS安裝指南來編譯框架妄迁。一旦你有了framework卵渴,直接拖拽到Xcode:
你也需要找到工程中的預(yù)編譯文件。這個(gè)文件通常在"ProjectName/Supporting Files/ProjectName-Prefix.pch"罗售。在這你需要增加一個(gè)包含語句去導(dǎo)入Opencv庫(kù)辜窑。然而,確保你包含Opencv在包含UIKit和Foundation之前寨躁,因?yàn)槟惆l(fā)現(xiàn)像最大值和最小值的宏定義的被定義多次的編譯錯(cuò)誤。例如前綴可能如下所示:
//
// Prefix header for all source files of the 'VideoFilters' target in the 'VideoFilters' project
//
#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
Example video frame processing project
User Interface
首先牙勘,我們創(chuàng)建一個(gè)簡(jiǎn)單的iOS工程职恳,例如Single View Application。然后方面,我們創(chuàng)建并且添加一個(gè)UIImageView和UIButton去啟動(dòng)攝像頭和顯示視頻幀放钦。故事版可以像這樣:
請(qǐng)務(wù)必將IBOutlets和 IBActions連接到相應(yīng)的ViewController。
@interface ViewController : UIViewController
{
IBOutlet UIImageView* imageView;
IBOutlet UIButton* button;
}
- (IBAction)actionStart:(id)sender;
@end
Adding the Camera
我們添加一個(gè)Camera控制器到一個(gè)頁(yè)面控制器并且在頁(yè)面被load時(shí)初始化:
#import <opencv2/highgui/cap_ios.h>
using namespace cv;
@interface ViewController : UIViewController
{
...
CvVideoCamera* videoCamera;
}
...
@property (nonatomic, retain) CvVideoCamera* videoCamera;
@end
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.videoCamera = [[CvVideoCamera alloc] initWithParentView:imageView];
self.videoCamera.defaultAVCaptureDevicePosition = AVCaptureDevicePositionFront;
self.videoCamera.defaultAVCaptureSessionPreset = AVCaptureSessionPreset352x288;
self.videoCamera.defaultAVCaptureVideoOrientation = AVCaptureVideoOrientationPortrait;
self.videoCamera.defaultFPS = 30;
self.videoCamera.grayscale = NO;
}
在這種情況下恭金,我們初始化相機(jī)并且把imageView
作為渲染每幀的顯示操禀。CvVideoCamera
是基于'AVFoundion'包裝的,所以我們能提供AVFoundation
攝像頭選擇屬性横腿。例如我們想要使用前置攝像頭颓屑,設(shè)置視頻大小為352x288和視頻方向(攝像頭通常是橫向輸出,當(dāng)你做一個(gè)豎向的應(yīng)用時(shí)會(huì)導(dǎo)致數(shù)據(jù)錯(cuò)位)
設(shè)置defaultFPS設(shè)置為攝像機(jī)的FPS耿焊, 如果處理少于預(yù)期的FPS揪惦,幀被自動(dòng)丟棄。
屬性grayscale=YES
使用不同的顏色空間罗侯,即 “YUV (YpCbCr 4:2:0)”器腋,而grayscale=NO
將輸出32位BGRA。
此外钩杰,我們必須手動(dòng)添加Opencv庫(kù)的依賴庫(kù)纫塌。最后,你在你的工程中至少有下面的框架:
- opencv2
- Accelerate
- AssetsLibrary
- AVFoundation
- CoreGraphics
- CoreImage
- CoreMedia
- CoreVideo
- QuartzCore
- UIKit
- Foundation
Processing frames
我們遵循代理模式讲弄,這在iOS中十分普遍措左,提供訪問每個(gè)攝像幀的權(quán)限〈共牵基本上媳荒, 視圖控制器必須實(shí)現(xiàn)CvVideoCameraDelegate
協(xié)議并且設(shè)置為視頻攝像頭的代理:
@interface ViewController : UIViewController<CvVideoCameraDelegate>
- (void)viewDidLoad
{
...
self.videoCamera = [[CvVideoCamera alloc] initWithParentView:imageView];
self.videoCamera.delegate = self;
...
}
#pragma mark - Protocol CvVideoCameraDelegate
#ifdef __cplusplus
- (void)processImage:(Mat&)image;
{
// Do some OpenCV stuff with the image
}
#endif
請(qǐng)注意我們?cè)谶@里使用了C++(cv::Mat)抗悍。重要提醒:你必須能重命名視圖控制器的后綴.m
為.mm
,以便能在Objective-C++ (Objective-C與 C++ 混編)下編譯成功钳枕。 然后缴渊,當(dāng)編譯器處理C++代碼文件時(shí)__cplusplus
被定義。因此__cplusplus
在哪里被定義我們代碼就放在哪個(gè)代碼塊里鱼炒。
Basic video processing
從這你能開始處理視頻幀了衔沼。例如下面代碼片的圖片顏色翻轉(zhuǎn):
- (void)processImage:(Mat&)image;
{
// Do some OpenCV stuff with the image
Mat image_copy;
cvtColor(image, image_copy, CV_BGRA2BGR);
// invert image
bitwise_not(image_copy, image_copy);
cvtColor(image_copy, image, CV_BGR2BGRA);
}
開始
最后,我們必須告訴攝像機(jī)準(zhǔn)確的start/stop工作昔瞧。接下來的代碼當(dāng)你按下button時(shí)啟動(dòng)攝像頭指蚁,假設(shè)你正確的連接用戶界面:
#pragma mark - UI Actions
- (IBAction)actionStart:(id)sender;
{
[self.videoCamera start];
}
Hints
盡可能的避免昂貴的矩陣復(fù)制操作,尤其你的目標(biāo)是實(shí)時(shí)處理自晰。如果可能凝化,盡可能的就地處理數(shù)據(jù)。
當(dāng)你工作在灰度數(shù)據(jù)時(shí)酬荞,一次設(shè)置grayscale = YES
作為YUV顏色空間來讓你直接訪問亮度平面搓劫。
Accelerate框架提供了一些CPU加速的DSP濾波器,這可以讓你更得心應(yīng)手混巧。