OpenCV iOS開發(一)——安裝(轉)
OpenCV是一個開源跨平臺的的計算機視覺和機器學習庫,可以用來做圖片視頻的處理、圖形識別、機器學習等應用。本文將介紹OpenCV iOS開發中的Hello World起步。
安裝
OpenCV安裝的方式有三種:
- 下載源代碼編譯
- 使用CocoaPods安裝
- 使用官方的framework
第一種方式太麻煩,而且我也不熟悉,想要自己編譯的可以去github下載編譯。
第二種方式很簡單,再podfile中加入pod ‘OpenCV-iOS‘, ‘~> 3.1‘
,然後運行pod install
就行,但是問題Cocoapods上面OpenCV的版本只有3.x的,沒有我想要的2.x的,而且我嘗試安裝了幾次,都因為坑爹的網絡以失敗告終。
第三種方式就是去官網下載,我下載的最新的2.4.13,後續的例子都是使用此版本進行開發,不過使用的時候還是有不少的坑,後面會提到。
使用 OpenCV
首先將下載好的opencv2.framework
添加到項目中,並且將OpenCV所需的依賴庫添加到項目中。
- libc++.tbd
- AVFoundation.framework
- CoreImage.framework
- CoreGraphics.framework
- QuartzCore.framework
- Accelerate.framework
如果要使用攝像頭做視頻處理,還需要添加以下兩個依賴庫:
- CoreVideo.framework
- CoreMedia.framework
- AssetsLibrary.framework
添加完依賴庫後我們就正式開始寫第一個Hello World了,因為OpenCV是C++寫的,所以引入項目中的文件需要使用Object-C++的兼容方式來寫,具體的做法就是將需要導入OpenCV頭文件的m
文件改成mm
文件,後續會先使用Object-C++對OpenCV進行封裝,然後就可以在Object-C中正常導入了。不熟悉C++語法的可以使用一下鏈接進行快速學習。
- X分鐘速成Y
- 向iOS開發者介紹C++(一)
- 向iOS開發者介紹C++(二)
下面要正式添加代碼了,在這個例子中我們可以給攝像頭做一個黑白反向的濾鏡。
mm
的文件中導入OpenCV的庫。
#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
三個庫即不會出錯了。
作者:前塵如夢
鏈接:http://www.jianshu.com/p/79f9c4200b9e
來源:簡書
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請註明出處。 轉至:http://www.jianshu.com/p/79f9c4200b9e
OpenCV iOS開發(一)——安裝(轉)