工業自動化網
發布采購單
官方微信 精彩呈現

一個最簡單的openCV Demo

   日期:2018-09-01     瀏覽:206    評論: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相關評論

推薦圖文
推薦編程
點擊排行
工業自動化網
產品檢索: A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
Processed in 1,590,685,999.281 second(s), 14 queries, Memory 0.64 M
篮球场地标准尺寸 1分钟一次的极速赛车骗局 山东11选5网上购买 七码中特你敢买吗 大地棋牌唯一指定下载 福建体彩31选7走式图 捕鱼大亨在线下载 五分彩开奖记录 单机游戏麻将下载大全 蓝筹股是什么意思 网上兼职赚钱网站