1. 程式人生 > >OpenCV iOS開發(一)——安裝(轉)

OpenCV iOS開發(一)——安裝(轉)

osi ctu ren png object-c 下載 eww load 信息

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.frameworkCoreMedia.frameworkAssetsLibrary.framework三個庫即不會出錯了。



作者:前塵如夢
鏈接:http://www.jianshu.com/p/79f9c4200b9e
來源:簡書
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請註明出處。 轉至:http://www.jianshu.com/p/79f9c4200b9e

OpenCV iOS開發(一)——安裝(轉)