iOS中使用opencv进行图像识别操作(一)步骤很多,这一篇只是讲了第一步.

转载 2016年12月05日 02:06:05

前言

OpenCV ,是一个开源的跨平台计算机视觉和机器学习库,通俗点的说,就是他给计算机提供了一双眼睛,一双可以从图片中获取信息的眼镜,从而完成人脸识别、去红眼、追踪移动物体等等的图像相关的功能。更多具体的说明可参见 OpenCV 官网

导入工程

导入 OpenCV 到 Xcode 的工程中还是比较简单的,从官网下载对应的 framework,直接丢到 Xcode 的工程中,然后在你想用 OpenCV 的地方引入 OpenCV 的头文件:

#import <opencv2/opencv.hpp>

或者直接在 PCH 文件中添加:

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

然后把使用到 OpenCV 中 C++方法的实现文件后缀名改成.mm,就可以开始使用 OpenCV 的方法了。看起来很简单,对吧?确实是很简单,不过这里有一些要注意的地方,我们一起来看看。

实际问题

首先说明,为何在 PCH 文件中引入 OpenCV 的头文件我们需要多加#ifdef __cpluseplus这一部分呢?这是因为 PCH 文件是一个会被所有的文件引入的头文件,而我们又希望 #import <opencv2/opencv.hpp>这部分只会被一些 C++实现文件编译,所以我们加上#ifdef __cpluseplus来表示这是 C++ 文件才会编译的,除了#ifdef __cpluseplus,还有#ifdef __OBJC__这样的宏来说明编译规则(按照 OC 文件编译),这样的宏多出现于一些会被多种类型的实现文件引用的头文件中。

另外注意另一个问题:如果一个头文件是C++类型的头文件,那么一定要保证所有直接或者间接引用这个头文件的实现文件都要为.mm或者.cpp,否则 Xcode 就不会把这个头文件当做 C++头文件来编译,就会出现最基本的#include <iostream>这种引用都会报出file not found 这样的编译错误的问题。我在编译的过程中,某个C++头文件 A.h 被 B.h 引用,然后 B.h 又被 C.m 引用,虽然 B 的实现文件是 B.mm ,但是仍然报出了之前说的那个错误, 感谢 StackOberflow 让我找到了问题发生的原因。所以对于 C++ 头文件的引用一定要注意,但凡是引用了 A.h 的实现部分,都必须是.mm或者.cpp后缀名。(同时我们也可以知道,Xcode 是根据头文件被引用的情况来判定头文件的编译 类型的)。

转换 UIImage 和 cv::Mat

在 OpenCV 中同常用 cv::Mat 表示图片,而 iOS 中则是 UIImage 来表示图片,因此我们就需要一些转换的方法,OpenCV 的官方教程中给吃了转换的方法,这里摘录如下:

UIImage To cv::Mat:


- (cv::Mat)cvMatFromUIImage:(UIImage *)image
{
  CGColorSpaceRef colorSpace = CGImageGetColorSpace(image.CGImage);
  CGFloat cols = image.size.width;
  CGFloat rows = image.size.height;

  cv::Mat cvMat(rows, cols, CV_8UC4); // 8 bits per component, 4 channels (color channels + alpha)

  CGContextRef contextRef = CGBitmapContextCreate(cvMat.data,                 // Pointer to  data
                                                 cols,                       // Width of bitmap
                                                 rows,                       // Height of bitmap
                                                 8,                          // Bits per component
                                                 cvMat.step[0],              // Bytes per row
                                                 colorSpace,                 // Colorspace
                                                 kCGImageAlphaNoneSkipLast |
                                                 kCGBitmapByteOrderDefault); // Bitmap info flags

  CGContextDrawImage(contextRef, CGRectMake(0, 0, cols, rows), image.CGImage);
  CGContextRelease(contextRef);

  return cvMat;
}

cv::Mat To UIImage:

-(UIImage *)UIImageFromCVMat:(cv::Mat)cvMat
{
  NSData *data = [NSData dataWithBytes:cvMat.data length:cvMat.elemSize()*cvMat.total()];
  CGColorSpaceRef colorSpace;

  if (cvMat.elemSize() == 1) {//可以根据这个决定使用哪种
      colorSpace = CGColorSpaceCreateDeviceGray();
  } else {
      colorSpace = CGColorSpaceCreateDeviceRGB();
  }

  CGDataProviderRef provider = CGDataProviderCreateWithCFData((__bridge CFDataRef)data);

  // Creating CGImage from cv::Mat
  CGImageRef imageRef = CGImageCreate(cvMat.cols,                                 //width
                                     cvMat.rows,                                 //height
                                     8,                                          //bits per component
                                     8 * cvMat.elemSize(),                       //bits per pixel
                                     cvMat.step[0],                            //bytesPerRow
                                     colorSpace,                                 //colorspace
                                     kCGImageAlphaNone|kCGBitmapByteOrderDefault,// bitmap info
                                     provider,                                   //CGDataProviderRef
                                     NULL,                                       //decode
                                     false,                                      //should interpolate
                                     kCGRenderingIntentDefault                   //intent
                                     );


  // Getting UIImage from CGImage
  UIImage *finalImage = [UIImage imageWithCGImage:imageRef];
  CGImageRelease(imageRef);
  CGDataProviderRelease(provider);
  CGColorSpaceRelease(colorSpace);

  return finalImage;
 }

iOS中使用opencv进行图像识别操作(一)步骤很多,这一篇只是讲了第一步.

前言 OpenCV ,是一个开源的跨平台计算机视觉和机器学习库,通俗点的说,就是他给计算机提供了一双眼睛,一双可以从图片中获取信息的眼镜,从而完成人脸识别、去红眼、追踪移动物体等等的图像相关的功能。...
  • a787188834
  • a787188834
  • 2016年12月05日 02:06
  • 3501

《现代操作系统(中文第三版)》课后习题——第六章 死锁

第六章 死锁 1.给出一个由策略产生的死锁的例子。 答:在美国,考虑总统选举,三个或更多的候选人正在争取某个政党的提名。初选结束后,当代表们到达党的选举大会时,可能没有候选人获得多数票,也没有任何代表...
  • cztqwan
  • cztqwan
  • 2017年05月28日 23:24
  • 1568

谈谈我学习图像处理的经历与收获

一个Java程序员转到图像处理的亲身经历,感悟与收获。
  • jia20003
  • jia20003
  • 2015年10月22日 11:47
  • 14402

Python下使用opencv等库进行国内答题卡选择题图像识别

背景:由于女票是一名人民教师,祖国园丁,无奈学校甚微简陋,连答题卡机器都没有,选择题只能老师人手一题一题的改。于是就有了这篇文章,我希望通过Python+opencv+imutils等库对答题卷的选择...
  • EdgarNg
  • EdgarNg
  • 2017年02月14日 14:11
  • 841

android中利用opencv进行图像识别

之前开发的时候老大让研究下图像识别的功能,同事推荐看看opencv,发现对于移动端来说opencv的资料和demo都比较少,现在整理下之前的工作成果。 首先是进行配置工作,先导入opencv的一个代...
  • xw13782513621
  • xw13782513621
  • 2017年03月08日 16:16
  • 5394

图像识别(8)——使用OpenCV预览USB摄像头+曝光设置

博主QQ:1356438802 QQ群:473383394——UVC&OpenCV473383394 平台:Win7 64bits + Visual Studio 2012 + OpenCV...
  • luoyouren
  • luoyouren
  • 2016年12月24日 12:25
  • 5415

关于使用ImageMagick和Tesseract进行简单数字图像识别

据说Tesseract可是世界排名第三的OCR神器,2010年又更新了3.0版本。Tesseract原先是HP写的,现在Open Source了。   下面介绍怎么用Tesseract配合Imag...
  • digimon
  • digimon
  • 2011年11月29日 13:43
  • 13362

图像识别:Android中使用OpenCV

看了网上的很多教程和官方http://opencv.willowgarage.com/wiki/Android提供的如何在Android上使用OpenCV的教程,照着一步一步的做最后总有些问题,不是A...
  • jingwen3699
  • jingwen3699
  • 2013年11月15日 16:15
  • 10207

移动设备上使用opencv 1.10做图像识别的例子 .

本文来自http://blog.csdn.net/hellogv/ ,引用必须注明出处!              上次说到了如何在WINCE/WM移植Opencv1.10,这次就说说如何在WM手机...
  • chenyujing1234
  • chenyujing1234
  • 2012年03月16日 17:41
  • 1127

beaglebone做图像识别——opencv1.0.0移植.part2.rar

  • 2016年08月22日 13:40
  • 46.03MB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:iOS中使用opencv进行图像识别操作(一)步骤很多,这一篇只是讲了第一步.
举报原因:
原因补充:

(最多只允许输入30个字)