codecamp

OpenCV iOS-视频处理

本教程介绍如何使用iPhone的摄像头和OpenCV处理视频帧。

先决条件:

  • Xcode 4.3或更高版本
  • iOS编程基础知识(Objective-C,Interface Builder)

在您的iOS项目中包含OpenCV库

OpenCV库作为一个所谓的框架,可以直接拖放到您的XCode项目中。从http://sourceforge.net/projects/opencvlibrary/files/opencv-ios/下载最新的二进制文件。或者按照本指南安装在iOS中手动编译框架。一旦有了框架,只需将其拖放到XCode中即可:

OpenCV iOS-视频处理

此外,您必须找到用于项目中所有头文件的前缀标题。该文件通常位于“ProjectName / Supporting Files / ProjectName-Prefix.pch”。在那里,您添加了一个include语句来导入opencv库。但是,在包含UIKit和Foundation之前,请确保包含opencv,因为否则您会收到一些奇怪的编译错误,一些宏如min和max被多次定义。例如,前缀头可能如下所示:

//
// 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

示例视频帧处理项目

用户界面

首先,我们创建一个简单的iOS项目,例如单视图应用程序。然后,我们创建并添加UIImageView和UIButton来启动相机并显示视频帧。故事板可能是这样的:

OpenCV iOS-视频处理

确保将IBOutlets和IBActions添加并连接到相应的ViewController:

@interface ViewController : UIViewController
{
    IBOutlet UIImageView* imageView;
    IBOutlet UIButton* button;
}
- (IBAction)actionStart:(id)sender;
@end

Adding the Camera

我们将视频控制器添加到摄像机控制器,并在视图加载时对其进行初始化:

#import <opencv2/videoio/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;
}

在这种情况下,我们初始化相机并提供imageView作为渲染每个帧的目标。CvVideoCamera基本上是围绕AVFoundation的包装,所以我们将AVGoundation摄像机的一些选项作为属性。例如,我们要使用前置摄像头,将视频尺寸设置为352x288和视频方向(视频摄像机通常以横向模式输出,当您设计肖像应用程序时会导致转置的数据)。

属性defaultFPS设置相机的FPS。如果处理速度比所需的FPS快,帧将自动丢弃。

属性灰度= YES导致不同的颜色空间,即“YUV(YpCbCr 4:2:0)”,而灰度=否则将输出32位BGRA。

另外,我们必须手动添加opencv框架的框架依赖关系。最后,您应该至少在您的项目中有以下框架:

  • opencv2
  • 加速
  • AssetsLibrary
  • AVFoundation
  • CoreGraphics中
  • CoreImage
  • CoreMedia
  • corevideo的
  • QuartzCore
  • UIKit的
  • 基础

OpenCV iOS-视频处理

处理框架

我们遵循在iOS中非常常见的授权模式,以提供对每个相机框架的访问。基本上,视图控制器必须实现CvVideoCameraDelegate协议,并且必须设置为摄像机的委托:

@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

请注意,我们在这里使用C ++(cv :: Mat)。重要:您必须将视图控制器的扩展名.m重命名为.mm,以便编译器在Objective-C ++(Objective-C和C ++混合)的假设下编译它。然后,当编译器正在处理C ++代码的文件时,__cplusplus被定义。因此,我们将代码放在__cplusplus定义的块中。

基本视频处理

从这里你可以开始处理视频帧。例如,以下代码段颜色会反转图像:

- (void)processImage:(Mat&)image;
{
    // Do some OpenCV stuff with the image
    Mat image_copy;
    cvtColor(image, image_copy, COLOR_BGR2GRAY);
    // invert image
    bitwise_not(image_copy, image_copy);
    //Convert BGR to BGRA (three channel to four channel)
    Mat bgr;
    cvtColor(image_copy, bgr, COLOR_GRAY2BGR);
    cvtColor(bgr, image, COLOR_BGR2BGRA);
}

开始!

最后,我们必须告诉相机实际上开始/停止工作。假设您正确连接了UI,按下按钮,以下代码将启动相机:

#pragma mark - UI Actions
- (IBAction)actionStart:(id)sender;
{
    [self.videoCamera start];
}

提示

尽量避免昂贵的矩阵复制操作,特别是如果您正在实时瞄准。当图像数据作为参考传递时,如果可能,就可以就地工作。

当您使用灰度数据时,请将灰度设置为YES,因为YUV色彩空间可让您直接访问亮度平面。

Accelerate框架提供了一些CPU加速DSP滤波器,在您的情况下可以方便使用。

OpenCV iOS-图像处理
Mat-基本图像容器
温馨提示
下载编程狮App,免费阅读超1000+编程语言教程
取消
确定
目录

OpenCV教程

OpenCV高级GUI和媒体(highgui模块)

OpenCV图像输入和输出(imgcodecs模块)

对象检测(objdetect模块)

计算摄影(照片模块)

图像拼接(拼接模块)

关闭

MIP.setData({ 'pageTheme' : getCookie('pageTheme') || {'day':true, 'night':false}, 'pageFontSize' : getCookie('pageFontSize') || 20 }); MIP.watch('pageTheme', function(newValue){ setCookie('pageTheme', JSON.stringify(newValue)) }); MIP.watch('pageFontSize', function(newValue){ setCookie('pageFontSize', newValue) }); function setCookie(name, value){ var days = 1; var exp = new Date(); exp.setTime(exp.getTime() + days*24*60*60*1000); document.cookie = name + '=' + value + ';expires=' + exp.toUTCString(); } function getCookie(name){ var reg = new RegExp('(^| )' + name + '=([^;]*)(;|$)'); return document.cookie.match(reg) ? JSON.parse(document.cookie.match(reg)[2]) : null; }