使用级联分类器检测脸部
本文学习如何使用OpenCV的 cv::CascadeClassifier
类检测脸部。我们加载一个经过训练的分类器XML文件,用这个文件识别脸部,并在识别到的脸部上画个方框。
准备
OpenCv自带经过训练的脸部识别分类器XML文件haarcascade_frontalface_alt2.xml。这个文件可以从 https://github.com/Itseez/opencv/tree/master/data/haarcascades获取到。
步骤
- 使用《Instant-OpenCV-for-iOS》-学习笔记-3的工程。
- 将haarcascade_frontalface_alt2.xml文件拖到xcode的项目侧边栏的
Supporting Files
目录下。 修改
ViewController.h
文件。加入CascadeClassifier
类型变量声明faceDetector
。这就是对象检测器。1
2
3
4
5
6
7
8
9
10
11
12#import <UIKit/UIKit.h>
#import <opencv2/opencv.hpp>
#import <opencv2/imgcodecs/ios.h>
using namespace cv;
@interface ViewController : UIViewController{
CascadeClassifier faceDetector;
}
@property (weak, nonatomic) IBOutlet UIImageView *imageView;
@end
修改 ViewController.mm中的viewDidLoad 方法。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
//加载haarcascade_frontalface_alt2.xml文件
NSString * cascadePath =[[NSBundle mainBundle] pathForResource:@"haarcascade_frontalface_alt2" ofType:@"xml"];
faceDetector.load([cascadePath UTF8String]);
//加载图片文件
NSString * path = [[NSBundle mainBundle] pathForResource:@"lena_std" ofType:@"tif"];
UIImage * image = [UIImage imageWithContentsOfFile:path];
//转换image中的UIImage * 格式图像到Mat格式,结果存到faceImage中
Mat faceImage;
UIImageToMat(image, faceImage);
//转换faceImage中的图像到单通道灰度图像,结果存到gray中
Mat gray;
cvtColor(faceImage, gray, COLOR_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);
//画框
Scalar magenta = Scalar(0,128,255);
rectangle(faceImage, tl, br, magenta,4,8,0);
}
//显示结果
imageView.image = MatToUIImage(faceImage);
}CMD+R 编译运行,检查结果
解释
- 我们使用了使用《Instant-OpenCV-for-iOS》-学习笔记-3的工程。当然也可以直接建立一个工程。然后加入OpenCV framework文件,在storyboard里加上UIImageView组件。
- 本例中,我们使用基于Haar分类器方法的人脸检测器类
cv::CascadeClassifier
。Haar分类器由Paul Viola提出,后由Rainer Lienhart发展。 haarcascade_frontalface_alt2.xml
文件包含了用于检测脸部正面特征的分类器参数。- 加载参赛需要将
NSString
对象转化为std::string
对象。使用UTF8String
方法将NSString
对象转化为std::string
对象。 - 使用
CascadeClassifier
类的detectMultiScale
方法在图像中找到脸部区域。 - 使用
cv::rectangle
函数在检测结果区域上加方框。 - 可以使用不同的图片或者不同的分类器XML文件进行试验。比如使用haarcascade_eye.xml可以得到这样的效果