推广 热搜:
 |  行业设备  |  机械制造  |  机器视觉  |  机械自动化  |  仪器仪表  |  工业机器人  |  编程开发  |  嵌入式  |  电子技术  |  工控自动化  |  电工电气 频道

一个最简单的openCV Demo

   日期:2018-09-01     浏览:109    评论:0    
核心提示:一直想研究openCV,这段时间终于静下心来做个学习笔记,边学边记,大部分内容都来自官网https://docs.opencv.org/3.3.1/, 从基
 一直想研究openCV,这段时间终于静下心来做个学习笔记,边学边记,大部分内容都来自官网https://docs.opencv.org/3.3.1/,  从基础开始,我把学习openCV中的过程和问题尽量记录下来(包括各种坑!!),希望能有条理的回顾这方面的知识,也希望能帮助到同样学习openCV的同学,暂时以ios平台为例,后期会整理android相关。


安装openCV运行环境(for IOS)

保证我们学习最新版本,建议大家去官方下载最新的source,我这边暂时按照搭建IOS开发环境的方式介绍:

官方推荐我们下载git库来获取源码:

 

  1.  
    cd ~/<my_working _directory>
  2.  
    git clone https://github.com/opencv/opencv.git

然后生成framework。

 

 

  1.  
    Building OpenCV from Source, using CMake and Command Line
  2.  
    Make symbolic link for Xcode to let OpenCV build scripts find the compiler, header files etc.
  3.  
    cd /
  4.  
    sudo ln -s /Applications/Xcode.app/Contents/Developer Developer
  5.  
    Build OpenCV framework:
  6.  
    cd ~/<my_working_directory>
  7.  
    python opencv/platforms/ios/build_framework.py ios

 

也可以通过cocoapod管理依赖。

也可以去首页直接下载ios的framework。

 

 

我是以从官网下载源码的方式,然后编译成framework,导入工程中

我编译源码报错:

 

  1.  
    Executing: ['cmake', '-GXcode', '-DAPPLE_frameWORK=ON', '-DCMAKE_INSTALL_PREFIX=install', '-DCMAKE_BUILD_TYPE=Release', '-DIOS_ARCH=armv7', '-DCMAKE_TOOLCHAIN_FILE=/Users/jiabl/work/openCV/opencv/platforms/ios/cmake/Toolchains/Toolchain-iPhoneOS_Xcode.cmake', '-DENABLE_NEON=ON', '/Users/jiabl/work/openCV/opencv', '-DCMAKE_C_FLAGS=-fembed-bitcode', '-DCMAKE_CXX_FLAGS=-fembed-bitcode'] in /Users/jiabl/work/openCV/ios/build/build-armv7-iphoneos
  2.  
    ============================================================
  3.  
    ERROR: [Errno 2] No such file or directory
  4.  
    ============================================================
  5.  
    Traceback (most recent call last):
  6.  
    File "opencv/platforms/ios/build_framework.py", line 112, in build
  7.  
    self._build(outdir)
  8.  
    File "opencv/platforms/ios/build_framework.py", line 104, in _build
  9.  
    self.buildOne(t[0], t[1], mainBD, cmake_flags)
  10.  
    File "opencv/platforms/ios/build_framework.py", line 186, in buildOne
  11.  
    execute(cmakecmd, cwd = builddir)
  12.  
    File "opencv/platforms/ios/build_framework.py", line 36, in execute
  13.  
    retcode = check_call(cmd, cwd = cwd)
  14.  
    File "/System/Library/frameworks/Python.framework/Versions/2.7/lib/python2.7/subprocess.py", line 535, in check_call
  15.  
    retcode = call(*popenargs, **kwargs)
  16.  
    File "/System/Library/frameworks/Python.framework/Versions/2.7/lib/python2.7/subprocess.py", line 522, in call
  17.  
    return Popen(*popenargs, **kwargs).wait()
  18.  
    File "/System/Library/frameworks/Python.framework/Versions/2.7/lib/python2.7/subprocess.py", line 710, in __init__
  19.  
    errread, errwrite)
  20.  
    File "/System/Library/frameworks/Python.framework/Versions/2.7/lib/python2.7/subprocess.py", line 1335, in _execute_child
  21.  
    raise child_exception
  22.  
    OSError: [Errno 2] No such file or directory
后来发现是cmake没有安装,安装方法如下,官方教程很清楚,这里不做介绍:

 

https://cmake.org/install/ 

安装或者更新好cmake,编译framework,需要等待数十分钟(编译了很多cpu版本,所以很慢),提示如下,编译成功。

在我们源码根目录下生成如下文件

 

ios/opencv2.framework

下面我们将framework导入ios工程中写一个openCV demo。

 

第一个openCV Demo

新建ios工程,将我们上面编译或者下载的openCV.framework导入工程即可(官方英文步骤很简单,做过ios开发的都知道怎么设置依赖外部库,这里不多说)
  1.  
    1、Create a new XCode project.
  2.  
     
  3.  
    2、Now we need to link opencv2.framework with Xcode. Select the project Navigator in the left hand panel and click on project name.
  4.  
     
  5.  
    3、Under the TARGETS click on Build Phases. Expand link Binary With Libraries option.
  6.  
     
  7.  
    4、Click on Add others and go to directory where opencv2.framework is located and click open
  8.  
     
  9.  
    5、Now you can start writing your application.
新建xcode工程后,我们就可以开始写一些openCV代码(注意用mm文件编写opencv代码,因为库是c++写的哦)。

首先是最基本的图片处理,根据官网的介绍,openCV中对图片的处理是通过Mat structure来做的,需要与ios的UIImage做转化。所以,我整理了一个CVUtil单例类,定义这些常用的API,下面是代码,同时第一个坑到来了:

我按照官网引入opencv头文件的时候,报错:

 

  1.  
    #ifdef __cplusplus
  2.  
    #import <opencv2/opencv.hpp>
  3.  
    #endif

 

发现报错代码中人家说了:

 

  1.  
    #if defined(NO)
  2.  
    # warning Detected Apple 'NO' macro definition, it can cause build conflicts. Please, include this header before any Apple headers.
  3.  
    #endif

 

原因是我引入头文件要在其他引入文件最上方,好吧,改正一下

CVUtil.h文件

 

  1.  
    #import <opencv2/opencv.hpp>
  2.  
    #import <Foundation/Foundation.h>
  3.  
    #import <UIKit/UIKit.h>
  4.  
    #import "include.h"
  5.  
     
  6.  
  7.  
    @interface CVUtil : NSObject
  8.  
     
  9.  
  10.  
    - (cv::Mat)cvMatFromUIImage:(UIImage *)image;
  11.  
     
  12.  
  13.  
    - (cv::Mat)cvMatGrayFromUIImage:(UIImage *)image;
  14.  
     
  15.  
  16.  
    -(UIImage *)UIImageFromCVMat:(cv::Mat)cvMat;
CVUtil.mm文件
  1.  
    - (cv::Mat)cvMatFromUIImage:(UIImage *)image{
  2.  
    CGColorSpaceRef colorSpace = CGImageGetColorSpace(image.CGImage);
  3.  
    CGFloat cols = image.size.width;
  4.  
    CGFloat rows = image.size.height;
  5.  
    cv::Mat cvMat(rows, cols, CV_8UC4); // 8 bits per component, 4 channels (color channels + alpha)
  6.  
    CGContextRef contextRef = CGBitmapContextCreate(cvMat.data, // Pointer to data
  7.  
    cols, // Width of bitmap
  8.  
    rows, // Height of bitmap
  9.  
    8, // Bits per component
  10.  
    cvMat.step[0], // Bytes per row
  11.  
    colorSpace, // Colorspace
  12.  
    kCGImageAlphaNoneSkipLast |
  13.  
    kCGBitmapByteOrderDefault); // Bitmap info flags
  14.  
    CGContextDrawImage(contextRef, CGRectMake(0, 0, cols, rows), image.CGImage);
  15.  
    CGContextRelease(contextRef);
  16.  
    return cvMat;
  17.  
    }
  18.  
     
  19.  
    - (cv::Mat)cvMatGrayFromUIImage:(UIImage *)image{
  20.  
    CGColorSpaceRef colorSpace = CGImageGetColorSpace(image.CGImage);
  21.  
    CGFloat cols = image.size.width;
  22.  
    CGFloat rows = image.size.height;
  23.  
    cv::Mat cvMat(rows, cols, CV_8UC1); // 8 bits per component, 1 channels
  24.  
    CGContextRef contextRef = CGBitmapContextCreate(cvMat.data, // Pointer to data
  25.  
    cols, // Width of bitmap
  26.  
    rows, // Height of bitmap
  27.  
    8, // Bits per component
  28.  
    cvMat.step[0], // Bytes per row
  29.  
    colorSpace, // Colorspace
  30.  
    kCGImageAlphaNoneSkipLast |
  31.  
    kCGBitmapByteOrderDefault); // Bitmap info flags
  32.  
    CGContextDrawImage(contextRef, CGRectMake(0, 0, cols, rows), image.CGImage);
  33.  
    CGContextRelease(contextRef);
  34.  
    return cvMat;
  35.  
    }
  36.  
     
  37.  
    -(UIImage *)UIImageFromCVMat:(cv::Mat)cvMat{
  38.  
    NSData *data = [NSData dataWithBytes:cvMat.data length:cvMat.elemSize()*cvMat.total()];
  39.  
    CGColorSpaceRef colorSpace;
  40.  
    if (cvMat.elemSize() == 1) {
  41.  
    colorSpace = CGColorSpaceCreateDeviceGray();
  42.  
    } else {
  43.  
    colorSpace = CGColorSpaceCreateDeviceRGB();
  44.  
    }
  45.  
    CGDataProviderRef provider = CGDataProviderCreateWithCFData((__bridge CFDataRef)data);
  46.  
    // Creating CGImage from cv::Mat
  47.  
    CGImageRef imageRef = CGImageCreate(cvMat.cols, //width
  48.  
    cvMat.rows, //height
  49.  
    8, //bits per component
  50.  
    8 * cvMat.elemSize(), //bits per pixel
  51.  
    cvMat.step[0], //bytesPerRow
  52.  
    colorSpace, //colorspace
  53.  
    kCGImageAlphaNone|kCGBitmapByteOrderDefault,// bitmap info
  54.  
    provider, //CGDataProviderRef
  55.  
    NULL, //decode
  56.  
    false, //should interpolate
  57.  
    kCGRenderingIntentDefault //intent
  58.  
    );
  59.  
    // Getting UIImage from CGImage
  60.  
    UIImage *finalImage = [UIImage imageWithCGImage:imageRef];
  61.  
    CGImageRelease(imageRef);
  62.  
    CGDataProviderRelease(provider);
  63.  
    CGColorSpaceRelease(colorSpace);
  64.  
    return finalImage;
  65.  
    }
上述方法官网是直接给出的,请自己复制到工程的util中使用。

 

下面我尝试做一个简单的例子,将一个图片转化为灰色


点击gray按钮,效果如下:

 

优化:
    上面我提到官网要求我们引入opencv库要在ios框架之前完成,我们还是按照官网推荐的方式,将#import<opencv2/opencv.hpp>写在pch文件中
  1.  
    Also you have to locate the prefix header that is used for all header files in the project. The file is typically located at "ProjectName/Supporting Files/ProjectName-Prefix.pch". There, you have add an include statement to import the opencv library. However, make sure you include opencv before you include UIKit and Foundation, because else you will get some weird compile errors that some macros like min and max are defined multiple times. For example the prefix header could look like the following:
  2.  
     
  1.  
    //
  2.  
    // Prefix header for all source files of the 'VideoFilters' target in the 'VideoFilters' project
  3.  
    //
  4.  
    #import <Availability.h>
  5.  
    #ifndef __IPHONE_4_0
  6.  
    #warning "This project uses features only available in iOS SDK 4.0 and later."
  7.  
    #endif
  8.  
    #ifdef __cplusplus
  9.  
    #import <opencv2/opencv.hpp>
  10.  
    #endif
  11.  
    #ifdef __OBJC__
  12.  
    #import <UIKit/UIKit.h>
  13.  
    #import <Foundation/Foundation.h>
  14.  
    #endif

       我们新建pch文件(ios8以后工程中可能不默认创建,需要我们手动创建),将引入写在pch中,让程序在预编译阶段完成对opencv库的引入,步骤如下:
第一步:


 
 
 
第二步:


第三步:

完成!

 
打赏
 
更多>同类编程
0相关评论

推荐图文
推荐编程
点击排行

网站首页  |  关于我们  |  联系方式  |  使用协议  |  版权隐私  |  网站地图  |  排名推广  |  广告服务  |  积分换礼  |  网站留言  |  RSS订阅  |  违规举报