linux opencv人脸检测,opencv 实现人脸检测(opencv3.3 + visual studio 2017)

最近搞一个人脸识别的项目练练手,opencv做人脸检测实在是强!!!

检测算法由haar特征算法实现

haar特征是一种很简单的算法,有很多实现的方式,下面几种很常见的haar特征计算方法 : A,B 俩矩阵特征,C三矩阵特征,D对角矩阵特征

8d7706cfb64c9c6e6a84992bdb842d1d.png

很通俗的来说,haar算法计算特征就是用一块区域内黑色的值减去白色的值。但是一张图片像素点是非常多的,如果用普通的方法去计算一块区域的值,效率相当低下。

这里有一种加速计算的方法--积分图:

定义如下:

61d264e524b1adf35cd2a1992a5f5373.png(维基百科贴过来的“—”)

积分图每一点(x,y)都是这个点对应左上角区域所有值的和

并且只需要遍历一遍图像就可得到积分图。

而对于任意一点(x,y) 积分图可这样计算 I(x,y)= i(x,y)+I(x-1,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 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

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);

}

最后检测效果:

17f84f535ec0c0c503cb3617060bf164.png

310bc5ca0ffdb86df7b90280e512eb29.png

全部代码如下:

#include

#include

#include

#include

#include

#include

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 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

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);

}

代码和分类器都已经上传,有需要的朋友可以下载。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值