OpenCV是一個開源跨平臺的的計算機視覺和機器學習庫,能夠用來作圖片視頻的處理、圖形識別、機器學習等應用。本文將介紹OpenCV iOS開發中的Hello World起步。html
OpenCV安裝的方式有三種:ios
第一種方式太麻煩,並且我也不熟悉,想要本身編譯的能夠去github下載編譯。c++
第二種方式很簡單,再podfile中加入pod 'OpenCV-iOS', '~> 3.1'
,而後運行pod install
就行,可是問題Cocoapods上面OpenCV的版本只有3.x的,沒有我想要的2.x的,並且我嘗試安裝了幾回,都由於坑爹的網絡以失敗了結。git
第三種方式就是去官網下載,我下載的最新的2.4.13,後續的例子都是使用此版本進行開發,不過使用的時候仍是有很多的坑,後面會提到。github
首先將下載好的opencv2.framework
添加到項目中,而且將OpenCV所需的依賴庫添加到項目中。網絡
若是要使用攝像頭作視頻處理,還須要添加如下兩個依賴庫:app
添加完依賴庫後咱們就正式開始寫第一個Hello World了,由於OpenCV是C++寫的,因此引入項目中的文件須要使用Object-C++的兼容方式來寫,具體的作法就是將須要導入OpenCV頭文件的m
文件改爲mm
文件,後續會先使用Object-C++對OpenCV進行封裝,而後就能夠在Object-C中正常導入了。不熟悉C++語法的可使用一下連接進行快速學習。機器學習
下面要正式添加代碼了,在這個例子中咱們能夠給攝像頭作一個黑白反向的濾鏡。
第一步是在咱們修改爲的mm
的文件中導入OpenCV的庫。ide
#import <opencv2/opencv.hpp> #import <opencv2/highgui/cap_ios.h>
而後添加一個UIImageView做爲顯示內容,而後使用OpenCV的CvVideoCamera對象來從攝像頭中獲取圖片顯示在UIImageView中,代碼以下:學習
@interface ViewController ()<CvVideoCameraDelegate>{ UIImageView *cameraView; CvVideoCamera *videoCamera; } @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; cameraView = [[UIImageView alloc] initWithFrame:self.view.frame]; [self.view addSubview:cameraView]; videoCamera = [[CvVideoCamera alloc] initWithParentView:cameraView]; videoCamera.defaultAVCaptureDevicePosition = AVCaptureDevicePositionFront; videoCamera.defaultAVCaptureSessionPreset = AVCaptureSessionPreset640x480; videoCamera.defaultAVCaptureVideoOrientation = AVCaptureVideoOrientationPortrait; videoCamera.defaultFPS = 30; videoCamera.grayscaleMode = NO; videoCamera.delegate = self; } - (void)viewDidAppear:(BOOL)animated { [super viewDidAppear:animated]; [videoCamera start]; } - (void)viewWillDisappear:(BOOL)animated { [super viewWillDisappear:animated]; [videoCamera stop]; } #pragma mark - CvVideoCameraDelegate - (void)processImage:(cv::Mat&)image { //在這兒咱們將要添加圖形處理的代碼 }
要將一個圖片進行黑白反轉,須要兩個步驟,首先將圖片轉成灰度圖片,而後將黑色和白色進行交換, 詳細的代碼以下:
- (void)processImage:(cv::Mat&)image { //在這兒咱們將要添加圖形處理的代碼 cv::Mat image_copy; //首先將圖片由RGBA轉成GRAY cv::cvtColor(image, image_copy, cv::COLOR_BGR2GRAY); //反轉圖片 cv::bitwise_not(image_copy, image_copy); //將處理後的圖片賦值給image,用來顯示 cv::cvtColor(image_copy, image, cv::COLOR_GRAY2BGR); }
其中Mat
是矩陣對象,在OpenCV中一張圖片信息在C++中使用Mat
對象來進行存儲,而在C語言中則使用IplImage
指針來存儲,cvtColor
就是就是圖片的內容進行指定格式的複製。
加上以上代碼後,運行後的視頻就會出現下面的效果了。
之前的版本,好比我之前使用的2.4.11的版本,在導入``opencv2.framework```添加到項目後,運行可能碰到如下錯誤:
Undefined symbols for architecture x86_64: "_jpeg_free_large", referenced from: _free_pool in opencv2(jmemmgr.o) "_jpeg_free_small", referenced from: _free_pool in opencv2(jmemmgr.o) _self_destruct in opencv2(jmemmgr.o) "_jpeg_get_large", referenced from: _alloc_large in opencv2(jmemmgr.o) _alloc_barray in opencv2(jmemmgr.o) "_jpeg_get_small", referenced from: _jinit_memory_mgr in opencv2(jmemmgr.o) _alloc_small in opencv2(jmemmgr.o) "_jpeg_mem_available", referenced from: _realize_virt_arrays in opencv2(jmemmgr.o) "_jpeg_mem_init", referenced from: _jinit_memory_mgr in opencv2(jmemmgr.o) "_jpeg_mem_term", referenced from: _jinit_memory_mgr in opencv2(jmemmgr.o) _self_destruct in opencv2(jmemmgr.o) "_jpeg_open_backing_store", referenced from: _realize_virt_arrays in opencv2(jmemmgr.o) ld: symbol(s) not found for architecture x86_64 clang: error: linker command failed with exit code 1 (use -v to see invocation)
通過網上搜索得知是缺乏了libjpeg.a
依賴庫,你能夠在網上搜索這個a文件,下載後使用lipo -info libjpeg.a
查看是否包含armv6 armv7 armv7s arm64
支持。固然也能夠直接下載libjpeg-turbo,安裝後直接今後路徑/opt/libjpeg-turbo/lib/libjpeg.a
複製加入到項目中。不過在最新的OpenCV 2.4.13版本已經不會這個錯誤提示了。
若是運行上面的例子出現出現如下錯誤:
Undefined symbols for architecture arm64: "_OBJC_CLASS_$_ALAssetsLibrary", referenced from: objc-class-ref in opencv2(cap_ios_video_camera.o) "_CMSampleBufferGetPresentationTimeStamp", referenced from: -[CvVideoCamera captureOutput:didOutputSampleBuffer:fromConnection:] in opencv2(cap_ios_video_camera.o) "_CMTimeMake", referenced from: -[CvVideoCamera createVideoDataOutput] in opencv2(cap_ios_video_camera.o) "_CMSampleBufferGetImageBuffer", referenced from: -[CaptureDelegate captureOutput:didOutputSampleBuffer:fromConnection:] in opencv2(cap_avfoundation.o) -[CvVideoCamera captureOutput:didOutputSampleBuffer:fromConnection:] in opencv2(cap_ios_video_camera.o) ld: symbol(s) not found for architecture arm64 clang: error: linker command failed with exit code 1 (use -v to see invocation)
這是由於咱們使用了攝像頭和視頻, 須要導入CoreVideo.framework
,CoreMedia.framework
,AssetsLibrary.framework
三個庫即不會出錯了。