OpenCV iOS开发(一)——安装

作者: 前尘如梦 | 来源:发表于2016-11-28 01:10 被阅读8028次

    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++语法的可以使用一下链接进行快速学习。

    下面要正式添加代码了,在这个例子中我们可以给摄像头做一个黑白反向的滤镜。
    第一步是在我们修改成的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三个库即不会出错了。

    相关文章

      网友评论

      • 863c73f31933:'opencv2/opencv.hpp' file not found,楼上,我也是安装的cocoapods,这里还是报错?
      • e441b6aa9bed:你好,请问一下怎么录制处理过后的视频并且保存出来呢
      • 香烟不灭:楼主,会用OpenCV 提取图片特征,用来发给服务器,进行AR识别 吗?有的话,能否给个思路,或者资料。谢谢。
        香烟不灭:@前尘如梦 谢谢。我研究研究
        前尘如梦:OpenCV有级联训练器,你可以训练图片的特征xml,然后使用特征点来识别
      • 冰三尺:我下载的是最新的3.3, 发现cap_ios.h文件没有了
        冰三尺:@hehtao OK ,多谢。
        hehtao:3.0以上是阉割版,编译iOS的库不好使,一般在移动端使用2.X的库
      • 冰三尺:OpenCV 目前最新的版本是3.x吧
      • Ericydong:发现有时候输出的视频被旋转了,帖主有没有遇到过这种情况?
        hehtao:输出视频被旋转是 AVCaptureSession 会出现,output 自个配置方向
      • hehtao:另外推荐两本书,也是OpenCV 官网的链接:<<instant-opencv-for-ios>>和<<iOS Application Development with OpenCV 3>> 全是英文版,不过读起来不是太难,没找到中文翻译,哪位若是找到了还望分享一下;下载地址(免积分): https://pan.baidu.com/s/1bpyabEZ
      • hehtao:补充两点:一.下载地址: https://opencv.org/releases.html; 二.使用CocoaPods 安装OpenCV,podfile 使用 pod 'OpenCV', '~> 2.4.13' 即可,试验发现3.0.0的库以上应该是阉割版的,缺少部分对iOS的支持文件;使用 pod 'OpenCV-iOS', '~> 3.1' 导入的库是动态库,如下:OpenCV (Computer Vision) for iOS as a dynamic library.
        pod 'OpenCV-iOS', '~> 3.1.1'
        - Homepage: https://github.com/edc1591/opencv-ios
        - Source: https://github.com/edc1591/opencv-ios.git
        - Versions: 3.1.1 [master repo]
        hehtao:@欺魄小妖 什么方式导入的? 具体引入的什么头文件?
        欺魄小妖:你好,我导入的是2.4.13 ,导入成功,引入头文件,发现里边的文件找不到,求解
        hehtao:使用源码编译详见官网:https://docs.opencv.org/master/d5/da3/tutorial_ios_install.html
      • 古子林:为何只有一篇?不是应该有个系列教学吗?
      • mjwz5294:大佬你好。想请教你一个问题:
        我建了一个videoFromCamVC,导入了<opencv2/videoio/cap_ios.h>,并在viewdidload里面只写一句:
        CvVideoCamera* testCam = [[CvVideoCamera alloc] init];
        报错:
        Apple Mach-O Linker (ld) Error Group
        "_OBJC_CLASS_$_CvVideoCamera", referenced from:
        clang: error: linker command failed with exit code 1 (use -v to see invocation)

        这里还没找到原因,请问你有没有解决过这个问题
        PS:
        1、我用cocoapod导入的opencv:pod 'OpenCV-iOS','~> 3.1.1’;
        2、已经使用过canny算法处理图片,且跑成功了;
        mjwz5294:用最新版本吧,时间久了都忘了,新版本,新语法,绝对能跑通的,只是要折腾
        hehtao:3.0以上应该是阉割版
        大菠萝98123:我也出现这个问题了是不是真机跑就这样,模拟器没问题,我换成2.4.13.2就好了
      • L了个H:能私聊么我QQ1434591364
      • 刘超_a594:导入一直报错,现在已经3.2的版本了,作者可以私聊吗
      • Siri_120b:能远程帮我安装一下嘛。弄了10个小时了,
      • 叫我马小帅:官网下载不好使那个网址 404了
      • 呵呵你妹521:你好,我的导入进去报错,可以指导一下吗
      • 学_iOS:赞一个 刚好解决了我的烦恼
        欺魄小妖:你好,怎么导入成功的

      本文标题:OpenCV iOS开发(一)——安装

      本文链接:https://www.haomeiwen.com/subject/qvcypttx.html