
三月,你不能跳吗? >>> 
我最近从事面部识别项目opencv 人脸检测,以练习我的技能. Opencv真的很擅长面部检测! !! !!
通过哈尔特征算法实现检测算法
Haar功能是一种非常简单的算法,有很多实现方法. 以下是一些常见的haar特征计算方法: A和B矩阵特征,C三重矩阵特征,D对角矩阵特征.


通常,haar算法通过从区域中的黑色值中减去白色值来计算特征. 但是,图像中有很多像素. 如果使用普通方法计算面积值,效率会很低.
这是加快计算的一种方法-整体图:
定义如下:
(“ —”在Wikipedia上发布)
积分图的每个点(x,y)是该区域中对应于左上角的所有值的总和
您只需遍历图像一次即可获得积分图.

对于任何点(x,y)积分图,I(x,y)= i(x,y)+ I(x-1opencv 人脸检测,y)+ I(x,y-1)-I(x- 1,y-1)
使用积分图可以非常有效地计算图像中的特征区域.
我在这里使用训练有素的haar级联分类器.
眼睛检测 haarcascade_eye_tree_eyeglasses.xml
人脸检测 haarcascade_frontalface_alt2.xml
检测思路:

首先将图片转换为灰度,然后将图片均匀化,在经过处理的图像矩阵中检测脸部区域,然后将脸部转圈以检测眼睛.
检测功能代码如下:
void DetectFace(Mat img,Mat imgGray) {
namedWindow("src", WINDOW_AUTOSIZE);
vector<Rect> faces, eyes;
faceCascade.detectMultiScale(imgGray, faces, 1.2, 5, 0, Size(30, 30));
for (auto b : faces) {
cout << "输出一张人脸位置:(x,y):" << "(" << b.x << "," << b.y << ") , (width,height):(" << b.width << "," << b.height << ")" << endl;
}
if (faces.size()>0) {
for (size_t i = 0; i<faces.size(); i++) {
putText(img, "ugly man!", cvPoint(faces[i].x, faces[i].y - 10), FONT_HERSHEY_PLAIN, 2.0, Scalar(0, 0, 255));
rectangle(img, Point(faces[i].x, faces[i].y), Point(faces[i].x + faces[i].width, faces[i].y + faces[i].height), Scalar(0, 0, 255), 1, 8);
cout << faces[i] << endl;
//将人脸从灰度图中抠出来
Mat face_ = imgGray(faces[i]);
eyes_Cascade.detectMultiScale(face_, eyes, 1.2, 2, 0, Size(30, 30));
for (size_t j = 0; j < eyes.size(); j++) {
Point eye_center(faces[i].x + eyes[j].x + eyes[j].width / 2, faces[i].y + eyes[j].y + eyes[j].height / 2);
int radius = cvRound((eyes[j].width + eyes[j].height)*0.25);
circle(img, eye_center, radius, Scalar(65, 105, 255), 4, 8, 0);
}
}
}
imshow("src", img);
}
最后检测效果:



整个代码如下:
#include <opencv/cv.h>
#include <opencv/highgui.h>
#include <opencv2/opencv.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
using namespace std;
using namespace cv;
void DetectFace(Mat,Mat);
CascadeClassifier faceCascade;
CascadeClassifier eyes_Cascade;
int main(int argc, char** argv) {
VideoCapture cap;
if (!cap.open(0)) {
cout << "打开失败!!" << endl;
return -1;
}
if (!faceCascade.load("C:\\Users\\cb\\source\\repos\\Project2\\x64\\Debug\\haarcascade_frontalface_alt2.xml") ) {
cout << "人脸检测级联分类器没找到!!" << endl;
return -1;
}
if (!eyes_Cascade.load("C:\\Users\\cb\\source\\repos\\Project2\\x64\\Debug\\haarcascade_eye_tree_eyeglasses.xml")) {
cout << "眼睛检测级联分类器没找到!!" << endl;
return -1;
}
Mat img, imgGray;
int fps = 60;
while (true) {
cap >> img;
cvtColor(img, imgGray, CV_BGR2GRAY);
equalizeHist(imgGray, imgGray);//直方图均匀化
DetectFace(img, imgGray);
waitKey(1000/fps);
}
return 0;
}
void DetectFace(Mat img,Mat imgGray) {
namedWindow("src", WINDOW_AUTOSIZE);
vector<Rect> faces, eyes;
faceCascade.detectMultiScale(imgGray, faces, 1.2, 5, 0, Size(30, 30));
for (auto b : faces) {
cout << "输出一张人脸位置:(x,y):" << "(" << b.x << "," << b.y << ") , (width,height):(" << b.width << "," << b.height << ")" << endl;
}
if (faces.size()>0) {
for (size_t i = 0; i<faces.size(); i++) {
putText(img, "ugly girl!", cvPoint(faces[i].x, faces[i].y - 10), FONT_HERSHEY_PLAIN, 2.0, Scalar(0, 0, 255));
rectangle(img, Point(faces[i].x, faces[i].y), Point(faces[i].x + faces[i].width, faces[i].y + faces[i].height), Scalar(0, 0, 255), 1, 8);
cout << faces[i] << endl;
//将人脸从灰度图中抠出来
Mat face_ = imgGray(faces[i]);
eyes_Cascade.detectMultiScale(face_, eyes, 1.2, 2, 0, Size(30, 30));
for (size_t j = 0; j < eyes.size(); j++) {
Point eye_center(faces[i].x + eyes[j].x + eyes[j].width / 2, faces[i].y + eyes[j].y + eyes[j].height / 2);
int radius = cvRound((eyes[j].width + eyes[j].height)*0.25);
circle(img, eye_center, radius, Scalar(65, 105, 255), 4, 8, 0);
}
}
}
imshow("src", img);
}
代码和分类器已上传,需要它的朋友可以下载.
代码云:
github:
本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/jisuanjixue/article-148036-1.html
中国为什么不在附近海域搞实弹演习