介绍

OpenCV是开源计算机视觉和机器学习库。包含成千上万优化过的算法。项目地址:http://opencv.org/about.html。官方文档:http://docs.opencv.org/modules/core/doc/intro.html。OpenCV已支持OpenCL OpenGL,也支持iOS和Android。OpenCV的API是C++的,所以在iOS中最佳实践是将用到OpenCV功能写一层Objective-C++封装。这些封装把OpenCV的C++API转化为安全的Objective-C API。

模块

  • core:简洁核心模块,基本函数,基本数据结构
  • imgproc:图像处理模块,线性和非线性图像滤波,几何图像转换,颜色空间转换,直方图等。
  • video:视频分析模块,运动估计,背景消除,物体跟踪算法
  • calib3d:基本多视角几何算法,单体和立体相机的标定,对象姿势估计,双目立体匹配算法和元素的三维重建
  • features2d:包含了显著特征检测算法,描述算子和算子匹配算法
  • objdetect:物体检测和一些预定义的物体的检测(如人脸,眼睛,杯子,人,汽车等)
  • ml:多种机器学习算法,如K均值,支持向量机和神经网络
  • highgui:简单易用接口,有视频捕捉,图像和视频编码功能,简单UI接口,iOS的是其中一个子集
  • gpu:GPU加速算法,iOS不可用
  • ocl:OpenCL通用算法,iOS不可用
  • 其它辅助模块,如用户贡献的算法

基础类和操作

OpenCV有几百个类,几个核心类可以参考文档:http://docs.opencv.org/modules/core/doc/core.html

cv::Mat:核心数据结构,可以用来表示N维矩阵,图像是2维矩阵的,cv::Mat是OpenCV中用的最多的。一个cv::Mat实例作用就是图像数据头,包含图像格式信息。图像中任一像素地址都可通过下面的指针运算得到:

  1. uchar *pixelPtr = cvMat.data + rowIndex * cvMat.step[0] + colIndex * cvMat.step[1]

每个像素的数据格式可以通过type()方法获得,这些数据格式包括:

  • 常用的每通道8位无符号整数的灰度图(1通道,CV_8UC1)
  • 常用的彩色图(3通道,CV_8UC3)
  • 不常用的CV_16SC3(每像素3通道,每通道使用16位有符号整数)
  • 不常用的CV_64FC4(每像素4通道,每通道使用64位浮点数)

cv::Algorithm:很多算法的抽象基类。

iOS中使用OpenCV

添加到自己项目中

Objective-C++

OpenCV的API在Objective-C++文件中使用,这里内存管理是需要注意的,ARC是无效的,所以assign需要在dealloc里将C++对象正确释放掉。更多的混用C++和Objective-C的细节参考Matt Galloway的教程:http://www.raywenderlich.com/62989/introduction-c-ios-developers-part-1

人脸识别器范例

范例源码:https://github.com/objcio/issue-21-OpenCV-FaceRec。范例是从iPhone摄像头获取视频流进行人脸的持续检测在屏幕上标出。用户点击一个脸孔会识别这个人,结果正确点“Correct”,错误要选择一个人名。人脸识别器

视频拍摄

OpenCV的highgui模块有个类CvVideoCamera,这个类把iPhone的摄像机抽象出来,通过一个代理(void)processImage:(cv::Mat&)image来获得视频流。实例可以这样设置:

  1. CvVideoCamera *videoCamera = [[CvVideoCamera alloc] initWithParentView:view];
  2. videoCamera.defaultAVCaptureDevicePosition = AVCaptureDevicePositionFront;
  3. videoCamera.defaultAVCaptureSessionPreset = AVCaptureSessionPreset640x480;
  4. videoCamera.defaultAVCaptureVideoOrientation = AVCaptureVideoOrientationPortrait;
  5. videoCamera.defaultFPS = 30;
  6. videoCamera.grayscaleMode = NO;
  7. videoCamera.delegate = self;

人脸检测

用优化过的Core Image提供的CIDetector类。

  1. CIDetector *faceDetector = [CIDetector detectorOfType:CIDetectorTypeFace context:context options:@{CIDetectorAccuracy: CIDetectorAccuracyHigh}];
  2. NSArray *faces = [faceDetector featuresInImage:image]; //faces中保存着每个面孔的CIFaceFeature实例。这个实例里有这个面孔的位置和宽高,眼睛,嘴位置等

使用OpenCV提供的一套物体检测功能,经过训练能够检测任何需要的物体。这个库自带了可以直接用的检测参数,比如脸,眼睛,嘴,身体,上半身,下半身和笑脸等。这些检测器称为Haar特征检测器。关于训练和检测过程可以参考这个论文http://www.multimedia-computing.de/mediawiki//images/5/52/MRL-TR-May02-revised-Dec02.pdf

  1. // 正面人脸检测器训练参数的文件路径
  2. NSString *faceCascadePath = [[NSBundle mainBundle] pathForResource:@"haarcascade_frontalface_alt2"
  3. ofType:@"xml"];
  4. const CFIndex CASCADE_NAME_LEN = 2048;
  5. char *CASCADE_NAME = (char *) malloc(CASCADE_NAME_LEN);
  6. CFStringGetFileSystemRepresentation( (CFStringRef)faceCascadePath, CASCADE_NAME, CASCADE_NAME_LEN);
  7. CascadeClassifier faceDetector; //这些参数可以在OpenCV包的data/haarcascades文件夹中找到
  8. faceDetector.load(CASCADE_NAME);
  9. //开始人脸检测
  10. cv::Mat img;
  11. vector<cv::Rect> faceRects;
  12. double scalingFactor = 1.1; //用不同的尺度遍历检测不同大小的人脸,scalingFactor决定每次遍历尺度会变大多少倍。
  13. int minNeighbors = 2; //拥有少于minNeighbors个符合条件的邻居像素人脸区域会被拒绝掉。
  14. int flags = 0; //1.x的遗留物,始终设置为0
  15. cv::Size minimumSize(30,30); //寻找的人脸区域大小的最小值
  16. //faceRects向量会包含对识别获得的所有人脸区域。识别的人脸图像可以通过cv::Mat的()运算符提取出,方式为:cv::Mat faceImg = img(aFaceRect)
  17. faceDetector.detectMultiScale(img, faceRects,
  18. scalingFactor, minNeighbors, flags
  19. cv::Size(30, 30) );

人脸识别

OpenCV自带三个人脸识别算法:Eigenfaces,Fisherfaces和局部二值模式直方图(LBPH)。详细参考OpenCV的文档:http://docs.opencv.org/modules/contrib/doc/facerec/facerec_tutorial.html#local-binary-patterns-histograms

下面的代码使用的是LBPH算法,它会根据用户输入自动更新,而不需要在每添加一个人或纠正一次出错的判断都要重新进行一次彻底的训练。

使用Objective-C++先将其封装,封装中暴露以下函数

  1. + (FJFaceRecognizer *)faceRecognizerWithFile:(NSString *)path;
  2. - (NSString *)predict:(UIImage*)img confidence:(double *)confidence;
  3. - (void)updateWithFace:(UIImage *)img name:(NSString *)name;
  4. //创建一个实例
  5. + (FJFaceRecognizer *)faceRecognizerWithFile:(NSString *)path {
  6. FJFaceRecognizer *fr = [FJFaceRecognizer new];
  7. fr->_faceClassifier = createLBPHFaceRecognizer();
  8. fr->_faceClassifier->load(path.UTF8String);
  9. return fr;
  10. }
  11. //预测
  12. - (NSString *)predict:(UIImage*)img confidence:(double *)confidence {
  13. cv::Mat src = [img cvMatRepresentationGray]; // UIImage 转化为 cv::Mat
  14. int label;
  15. self->_faceClassifier->predict(src, label, *confidence);
  16. return _labelsArray[label]; //_labelsArray是int和string对应关系数组
  17. }
  18. //通过用户的选择更新人脸识别器
  19. - (void)updateWithFace:(UIImage *)img name:(NSString *)name {
  20. cv::Mat src = [img cvMatRepresentationGray];
  21. NSInteger label = [_labelsArray indexOfObject:name];
  22. if (label == NSNotFound) {
  23. [_labelsArray addObject:name];
  24. label = [_labelsArray indexOfObject:name];
  25. }
  26. vector<cv::Mat> images = vector<cv::Mat>();
  27. images.push_back(src);
  28. vector<int> labels = vector<int>();
  29. labels.push_back((int)label);
  30. self->_faceClassifier->update(images, labels);
  31. }

预测,反馈,更新循环,这就是监督式学习:http://zh.wikipedia.org/wiki/%E7%9B%A3%E7%9D%A3%E5%BC%8F%E5%AD%B8%E7%BF%92

文/星光社的戴铭(简书作者)
原文链接:http://www.jianshu.com/p/96be2417cc98
著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”。

OpenCV学习 物体检测 人脸识别 填充颜色的更多相关文章

  1. [PyImageSearch] Ubuntu16.04 使用深度学习和OpenCV实现物体检测

    上一篇博文中讲到如何用OpenCV实现物体分类,但是接下来这篇博文将会告诉你图片中物体的位置具体在哪里. 我们将会知道如何使用OpenCV‘s的dnn模块去加载一个预训练的物体检测网络,它能使得我们将 ...

  2. 学习笔记TF058:人脸识别

    人脸识别,基于人脸部特征信息识别身份的生物识别技术.摄像机.摄像头采集人脸图像或视频流,自动检测.跟踪图像中人脸,做脸部相关技术处理,人脸检测.人脸关键点检测.人脸验证等.<麻省理工科技评论&g ...

  3. 利用modelarts和物体检测方式识别验证码

    近来有朋友让老山帮忙识别验证码.在github上查看了下,目前开源社区中主要流行以下几种验证码识别方式: tesseract-ocr模块: 这是HP实验室开发由Google 维护的开源 OCR引擎,内 ...

  4. OpenCV 学习笔记 05 人脸检测和识别

    本节将介绍 Haar 级联分类器,通过对比分析相邻图像区域来判断给定图像或子图像与已知对象是否匹配. 本章将考虑如何将多个  Haar 级联分类器构成一个层次结构,即一个分类器能识别整体区域(如人脸) ...

  5. OpenCV 学习笔记 05 人脸检测和识别 AttributeError: module 'cv2' has no attribute 'face'

    1 环境设置: win10 python 3.6.8 opencv 4.0.1 2 尝试的方法 在学习人脸识别中,遇到了没有 cv2 中没有 face 属性.在网上找了几个方法,均没有成功解决掉该问题 ...

  6. OpenCV学习代码记录——人脸检测

    很久之前学习过一段时间的OpenCV,当时没有做什么笔记,但是代码都还在,这里把它贴出来做个记录. 代码放在码云上,地址在这里https://gitee.com/solym/OpenCVTest/tr ...

  7. 使用OpenCV和Python进行人脸识别

    介绍 人脸识别是什么?或识别是什么?当你看到一个苹果时,你的大脑会立刻告诉你这是一个苹果.在这个过程中,你的大脑告诉你这是一个苹果水果,用简单的语言来说就是识别.那么什么是人脸识别呢?我肯定你猜对了. ...

  8. OpenCV平面物体检测

    平面物体检测 这个教程的目标是学习如何使用 features2d 和 calib3d 模块来检测场景中的已知平面物体. 测试数据: 数据图像文件,比如 “box.png”或者“box_in_scene ...

  9. opencv+python3.4的人脸识别----2017-7-19

    opencv3.1  +  python3.4 第一回合(抄代码,可实现):人脸识别涉及一个级联表,目前能力还无法理解. 流程:1.读取图像---2.转换为灰度图---3.创建级联表---4.对灰度图 ...

随机推荐

  1. Qt操作xml文件(增删改功能)

    这个例子是在根据网上博客<Qt数据库(XML)>改写的一个操作XML的实现. 借鉴了很多里面的代码,大家可以结合上面的博客对照,相信你肯定会对XML的操作熟练起来. 我建立的是Qwidge ...

  2. loadView在App启动时到底都干了些什么?

    loadView在App启动时到底都干了些什么? 查阅苹果官方文档如下: 1. 当你访问一个ViewController的view属性时,如果此时view的值是nil,那么,ViewControlle ...

  3. iOS XML  解析(原生的)

    #import <UIKit/UIKit.h> @interface AppDelegate : UIResponder <UIApplicationDelegate> @pr ...

  4. 第8章 委托、Lamdba表达式和事件

    本章内容: 委托    Lambda表达式 事件 8.1.3   简单的委托示例 首先定义一个类MathOperations,它有两个静态方法,对double类型的值执行两个操作. public cl ...

  5. crsctl stat res -t 和 crsctl stat res -init -t

    11.2.0.2的grid infrastructure中crsctl stat res命令不再显示如ora.cssd.ora.ctssd.ora.diskmon等基础资源的信息.但是查看这些基础资源 ...

  6. Java5、Java6、Java7的新特性

    Java5 Java 5添加了8个语言特性:泛型,类型安全枚举,注解,自动装箱和拆箱,增强的循环,静态导入,可变参数,协变返回类型. 1.泛型 Generics: 引用泛型之后,允许指定集合里元素的类 ...

  7. 寻找第K大的数

    在一堆数据中查找到第k个大的值. 名称是:设计一组N个数,确定其中第k个最大值,这是一个选择问题,解决这个问题的方法很多. 所谓“第(前)k大数问题”指的是在长度为n(n>=k)的乱序数组中S找 ...

  8. Inventory Pro 装备拾取的实现

    以后都按照插件使用,提出问题,回答问题的方式来进行总结和学习 效果图 1.运行相关的例子,场景中出现4个矩形,这4个矩形是用来模拟物品掉落的包裹,移动Player靠近物品 2.使用鼠标点击物品正方体, ...

  9. C++Primer 第六章

    //1.我们通过调用运算符来执行函数.调用运算符的形式是一对圆括号,他作用于一个表达式,该表达式是一个函数或者指向函数的指针.圆括号之内是用逗号分隔的实参列表,用于初始化函数形参.调用表达式的类型就是 ...

  10. javabean实体类对象转为Map类型对象的方法(转发)

    //将javabean实体类转为map类型,然后返回一个map类型的值 public static Map<String, Object> beanToMap(Object obj) { ...