基于OpenCV的人脸识别[iOS开发笔记(2)]
开始了OpenCV的试水工作了。。。
1.Get ready
在OpenCV中我们会使用函数cv::CascadeClassifier 来进行人脸检测。但是在使用本函数之前我们需要添加一个XML文件对该函数进行训练。最后用一个小红色方块将人脸表示出来
(当然Apple自带的函数也是可以进行人脸检测(CIDetector )的,但是CascadeClassifier除了人脸检测还可以检测各种其他部位,超强大有木有~~)
2.如何实现
我们将用一下四步来实现人脸检测的过程。
#添加XML文件到工程中
#创建函数cv::CascadeClassifier(使用XML文件内容)
#检测一张图像中的人脸
#画一个红色小四方形
3.习惯性的上代码
#import "ViewController.h" #import <opencv2/opencv.hpp> #import <opencv2/imgproc/types_c.h> #import <opencv2/imgcodecs/ios.h> @interface ViewController () { cv::CascadeClassifier faceDetector; } @property (weak, nonatomic) IBOutlet UIImageView *imgView; @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; // 添加xml文件 NSString* cascadePath = [[NSBundle mainBundle] pathForResource:@"haarcascade_frontalface_alt" ofType:@"xml"]; faceDetector.load([cascadePath UTF8String]); //上传图片 UIImage *image = [UIImage imageNamed:@"lena1.png"]; cv::Mat faceImage; UIImageToMat(image, faceImage); // 转为灰度 cv::Mat gray; cvtColor(faceImage, gray, CV_BGR2GRAY); // 检测人脸并储存 std::vector<cv::Rect>faces; faceDetector.detectMultiScale(gray, faces,1.1,2,0|CV_HAAR_SCALE_IMAGE,cv::Size(30,30)); // 在每个人脸上画一个红色四方形 for(unsigned int i= 0;i < faces.size();i++) { const cv::Rect& face = faces[i]; cv::Point tl(face.x,face.y); cv::Point br = tl + cv::Point(face.width,face.height); // 四方形的画法 cv::Scalar magenta = cv::Scalar(255, 0, 255); cv::rectangle(faceImage, tl, br, magenta, 4, 8, 0); } self.imgView.image = MatToUIImage(faceImage); }
4.看结果
5.友情提示
建议使用Auto Layout
布局 + Image Assets
管理各个分辨率的图片 + Interface Builder
(xib+storyboard)构建UI,Size Classes
在低版本iOS系统的表现未知。
想要这套手动适配方案,起码你的工程需要部署在iOS6+,还不用AutoLayout布局的会死的蛮惨
6.解惑
为什么一定要添加xml文件呢?
其实这个xml文件就是对人脸石识别的初始化(初始化数据by Paul Viola and later extended by Rainer Lienhart),现在已经成为一种人脸识别的标准了。
为了能够把xml文件成功倒入,我们需要把NSString object 转化为 std::string(使用UTF8String)
经过以上的准备工作后我们就可以使用方法detectMultiScale进行人脸检测了。
方法detectMultiScale有四个参数。分别为:
scaleFactor :制定循环递减的图片尺寸
minNeighbors :制定保留数据的矩形大小
CV_HAAR_SCALE_IMAGE :这是一个标志,它指定算法缩放图像,而不是检测器。它有助于实现最佳的性能