首页 > 代码库 > 翻译:Mastering OpenCV with Practical Computer Vision Projects(第8章)(二)

翻译:Mastering OpenCV with Practical Computer Vision Projects(第8章)(二)

/******************************************************************************************************************************************************************************************翻译:Mastering 请接着上一篇:OpenCV with Practical Computer Vision Projects(第8章)(一)继续阅读

                                                                 欢迎转载!请注明出处

***********************************************************************************************************************************/

         相比于人类可以通过比较脸部的不同来有效区分不同的人,基于Haar和LBP特征的检测器可以通过训练进而从大量的人脸图像中寻找出指定人脸,这些训练的信息一般存储在XML文件中,后面将会用到。对于分类器的训练,一般至少需要1000张正脸照和1000张非脸部的照片,比如树叶、车、文本之类的。训练的过程可能会很耗时,在一个双核电脑上,一般LBP分类器需要训练几个小时,而Haar分类器可能需要一周。幸运的是,OpenCV中已经包含了一些预先训练好的分类器供我们使用!我们可以选择Haar或LBP的,不同目标特征的分类器,去检测正脸、侧脸,眼睛、鼻子和嘴巴,我们仅需要根据需求加载不同的XML文件即可。

        使用OpenCV执行人脸检测

        上文已经提到,在OpenCV2.4之后,发行版中已经包含许多已经训练好的分类器,他们以XML文件形式存储,我们可以根据不同的意图选择不同的XML文件。下面的表格中列出了一些常用的XML文件:


扩展:目前最新的OpenCV2.4.9版本中的预分类器已经有好多了,他们处在文件目录D:\OpenCV-4.9\opencv\sources\data下:打开后里面有三个文件夹,分别为:haarcacsdes,LBPcacsdes和hogcacsdes。分别打开他们,你会看到如下的信息:(这段文字包括下面这幅图不是原文中的)

对于我们的人脸识别项目,我们希望能够检测出正脸,因此我们使用LBP脸部检测器,主要因为它速度快且不受许可问题的困扰。请注意虽然OpenCV2.X版本之后库中包含有预先训练好的LBP人脸检测器,但是它的精度并不高,如果你想要获得很高的精度,那么你可能需要重新训练你自己的LBP检测器或者使用Haar检测器。

Loading a Haar or LBP detector for object or face detection
在进行目标检测之前,我们首先要做的是加载这些已经训练好的XML文件,我们一般通过以下方式:
<span style="font-size:18px;">CascadeClassifier faceDetector;
faceDetector.load(faceCascadeFilename);</span>
这一步可以通过不同的文件名加载相应的Haar或LBP检测器,这里经常会犯的错误是文件的路径不对,进而加载失败,文件的路径不是绝对的,而是依赖你构建环境。

Detecting an object using the Haar or LBP Classifier
我们加载完分类器后,我们就可以使用它检测每一帧视频画面中的人脸了。但是在检测之前我们还需要对视频画面做一些预处理,主要通过以下步骤:
  1. 灰度化:人脸检测仅是在灰度图像上进行的,因此我们需要将相机捕获到的视频帧进行灰度化处理。
  2. 收缩图像:人脸检测的速度主要依赖于输入图像的尺寸,(大图像的检测速度很慢,而小图像的检测速度回很快,)检测的可靠性即使在很小的尺寸下也很好。所以我们应该收缩图像到最合适的尺寸。
  3. 直方图均衡化:人脸检测在低照度的情况下检测效果不好,因此我们需要通过直方图均衡化来提高其亮度和对比度。
Grayscale color conversion
我们可以使用cvtColor()函数轻松的实现将RGB图像转化为灰度图像,但是这样做的前提是我们使用的不是灰度摄像机。转化时我们需要制定原图像的格式,一般桌面电脑捕获的是RGB三通道图像,移动设备捕获的是BGRA四通道图像。因此我们的代码中要允许三种输入图片形式,如下:
	Mat gray;
	if (img.channels() == 3)
	{
		cvtColor(img,gray,CV_BGR2GRAY);
	}
	else if (img.channels() == 4)
	{
		cvtColor(img,gray,CV_BGRA2GRAY);
	}
	else
	{
		gray = img;
	}
shrinking the camera image
我们可以使用resize()来将图像缩放到指定的大小,也可以按比例缩放。对于图像尺寸大于240×240像素的情况,人脸识别就可以很好的使用了,因为他可以搜寻到任何尺寸大于20×20像素的人脸。下面我们将图像宽度设定为320,不管输入时VGA网络摄像头还是高清摄像头。有一点需要注意,在检测完成后要记得把检测结果扩大到原先的尺寸,因为你是在缩放的图像中检测的,所以结果也是缩放的。我们必须确保缩放后的图像看起来不会显得太胖或者太瘦。比如一个800×400的图像缩放到300×200时会使得图像中的人看起来比较瘦,因此我们需要使缩放后的图像与原图像有同样的宽高比。

	const int DETECTION_WIDTH = 320;
	Mat smallImg;
	float scale = img.cols/(float) DETECTION_WIDTH;
	if (img.cols>DETECTION_WIDTH)
	{
		int scaleHeight = cvRound(img.rows/scale);
		resize(img,smallImg,Size(DETECTION_WIDTH,scaleHeight));
	} 
	else
	{
		smallImg = img;
	}
Histogram equalization

我们可以通过直方图均衡化来提高图像的亮度和对比度。有时候它会使得图像看起来比较奇怪,但是实际上,他提高了图像的亮度和对比度,有助于人脸的检测。直翻图均衡化equalizeHist()函数的用法如下:
	Mat equalizedImg;
	equalizeHist(inputImg,equalizedImg);

detecting the face
现在我们已经完成将图像灰度化、缩放到合适尺寸以及直方图均衡化处理,下一步我们将使用CascadeClassifier::detectMultiScale()这个函数去检测人脸。首先我们需要向此函数传递一些参数,如下:
  • minFeatureSize:这个参数决定了我们检测的人脸的最小尺寸,一般我们会设定为20×20或者30×30,当然这个值需要根据你使用的图像的尺寸来决定,如果你使用的是手机摄像头或是电脑的摄像头,这些情况下脸部一般距离摄像头较近,你可以将最小尺寸设定为80×80,这样做会大大提高检测速度。但如果你想检测距离摄像头很远的脸部,比如沙滩上的朋友,那么你需要将这个尺寸设定为20×20.
  • searchScaleFactor:这个参数决定了可以检测多有多少不同尺寸的脸部,一般将其设定为1.1。如果想让检测速度快些,可以设定为1.2,但是可能会有一些脸部会漏检。
  • minNeighbors:这个参数表示检测器对检测到的人脸的把握,一般我们设定为3,但是如果你想要更可靠的检测结果,你可以适当增大这个参数,当然有可能会有很多脸部将检测不到。
  • flags:这个参数是让你选择搜索方式,比如是否搜索所有的脸部(这是默认模式),或者仅搜索最大的脸部(CASCADE_FIND_BIGGEST_OBJECT)。如果仅搜索最大的脸部,检测速度回很快。还有一些其他参数可以使用,他们可以使得检测速度提升一到两成,比如CASCADE_DO_ROUGH_SEARCH或者CASCADE_SCALE_IMAGE。
函数detectMultiScale()的输出时一个vector<Rect>,比如你检测到连个脸部,它将输出两个矩形。
	int flags = CASCADE_SCALE_IMAGE;
	Size minFeatureSize(20,20);
	float searchScaleFactor = 1.1f;
	int minNeighbors = 4;
	std::vector<Rect> faces;
	faceDetector.detectMultiScale(img,faces,searchScaleFactor,minNeighbors,flags,minFeatureSize);

原来翻译文章写博客这么费劲啊......唉,还有好多,今天先翻到这,,
未完待续。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。