首页 > 编程 > Python > 正文

OpenCV实现人脸识别

2020-02-23 04:31:37
字体:
来源:转载
供稿:网友

主要有以下步骤:

1、人脸检测

2、人脸预处理

3、从收集的人脸训练机器学习算法

4、人脸识别

5、收尾工作

人脸检测算法:

基于Haar的脸部检测器的基本思想是,对于面部正面大部分区域而言,会有眼睛所在区域应该比前额和脸颊更暗,嘴巴应该比脸颊更暗等情形。它通常执行大约20个这样的比较来决定所检测的对象是否为人脸,实际上经常会做上千次。

基于LBP的人脸检测器基本思想与基于Haar的人脸检测器类似,但它比较的是像素亮度直方图,例如,边缘、角落和平坦区域的直方图。

这两种人脸检测器可通过训练大的图像集找到人脸,这些图像集在opencv中存在XML文件中以便后续使用。

这些级联分类检测器通常至少需使用1000个独特的人脸图像和10000个非人脸图像作为训练,训练时间一般LBP要几个小时,

Haar要一个星期。

项目中的关键代码如下:

initDetectorsfaceCascade.load(faceCascadeFilename);eyeCascade1.load(eyeCascadeFilename1);eyeCascade2.load(eyeCascadeFilename2);initWebcamvideoCapture.open(cameraNumber);cvtColor(img, gray, CV_BGR2GRAY);//有需要则缩小图片使检测运行更快,之后要恢复原来大小resize(gray, inputImg, Size(scaledWidth, scaledHeight));equalizeHist(inputImg, equalizedImg);cascade.detectMultiScale(equalizedImg......);

人脸预处理:

实际中通常训练(采集图像)和测试(来自摄像机图像)的图像会有很大不同,受(如光照、人脸方位、表情等),

结果会很差,因此用于训练的数据集很重要。

人脸预处理目的是减少这类问题,有助于提高整个人脸识别系统的可靠性。

人脸预处理的最简单形式就是使用equalizeHist()函数做直方图均衡,这与人脸检测那步一样。

实际中,为了让检测算法更可靠,会使用面部特征检测(如,检测眼睛、鼻子、嘴巴和眉毛),本项目只使用眼睛检测。

使用OpenCV自带的训练好的眼部探测器。如,正面人脸检测完毕后,得到一个人脸,在使用眼睛检测器提取人脸的左眼区域和右眼区域,并对每个眼部区域进行直方图均衡。

这步涉及的操作有以下内容:

1、几何变换和裁剪

人脸对齐很重要,旋转人脸使眼睛保持水平,缩放人脸使眼睛之间距离始终相同,平移人脸使眼睛总是在所需高度上水平居中,

裁剪人脸外围(如图像背景、头发、额头、耳朵和下巴)。

2、对人脸左侧和右侧分别用直方图均衡

3、平滑

用双边滤波器来减少图像噪声

4、椭圆掩码

将剩余头发和人脸图像背景去掉

项目中的关键代码如下:

detectBothEyes(const Mat &face, CascadeClassifier &eyeCascade1, CascadeClassifier &eyeCascade2,Point &leftEye, Point &rightEye, Rect *searchedLeftEye, Rect *searchedRightEye);topLeftOfFace = face(Rect(leftX, topY, widthX, heightY));//在左脸区域内检测左眼detectLargestObject(topLeftOfFace, eyeCascade1, leftEyeRect, topLeftOfFace.cols);//右眼类似,这样眼睛中心点就得到了leftEye = Point(leftEyeRect.x + leftEyeRect.width/2, leftEyeRect.y + leftEyeRect.height/2);//再得到两眼的中点,然后计算两眼之间的角度Point2f eyesCenter = Point2f( (leftEye.x + rightEye.x) * 0.5f, (leftEye.y + rightEye.y) * 0.5f );//仿射扭曲(Affine Warping)需要一个仿射矩阵rot_mat = getRotationMatrix2D(eyesCenter, angle, scale);//现在可变换人脸来得到检测到的双眼出现在人脸的所需位置warpAffine(gray, warped, rot_mat, warped.size());//先对人脸左侧和右侧分开进行直方图均衡equalizeHist(leftSide, leftSide);equalizeHist(rightSide, rightSide);//再合并,这里合并时左侧1/4和右侧1/4直接取像素值,中间的2/4区域像素值通过一定计算进行处理。//双边滤波bilateralFilter(warped, filtered, 0, 20.0, 2.0);//采用椭圆掩码来删除一些区域filtered.copyTo(dstImg, mask);            
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表