利用OpenCV自带的xml文件,实时检测摄像头中人脸与眼睛。
opencv3/C++
detectMultiScale()参数说明:
//在输入图像中检测不同大小的对象。检测到的对象作为矩形列表返回。
void detectMultiScale(
InputArray image,//CV_8U类型图像
CV_OUT std::vector<Rect>& objects,//包含检测到的对象的矩形
double scaleFactor = 1.1,//指定在每个图像比例下图像大小减少的参数。
int minNeighbors = 3, //指定每个候选矩形必须保留多少个邻居。
int flags = 0,//与旧函数cvHaarDetectObjects中的相同
Size minSize = Size(),//最小可能的对象大小
Size maxSize = Size() //最大可能的对象大小
);
人脸与眼睛的检测示例:
注释掉的部分为绘制眼睛移动的轨迹。
#include<opencv2/opencv.hpp>
using namespace cv;
//人脸与眼睛检测与定位
int main()
{
CascadeClassifier faceCascader, eyeCascader;
String filename1 = "D:/opencv3.1.0/opencv/tools/opencv_contrib/install/etc/haarcascades/haarcascade_frontalface_alt.xml";
String filename2 = "D:/opencv3.1.0/opencv/tools/opencv_contrib/install/etc/haarcascades/haarcascade_eye.xml";
//std::vector<Point> pt; //绘制轨迹
if (!faceCascader.load(filename1))
{
printf("can not load the face feature data \n");
return -1;
}
if (!eyeCascader.load(filename2))
{
printf("can not load the eye feature data \n");
return -1;
}
namedWindow("input", WINDOW_AUTOSIZE);
VideoCapture capture;
capture.open(0);
Mat frame, gray, src;
std::vector<Rect> faces, eyes;
while (capture.read(frame))
{
flip(frame, frame, 1);
src = frame;
cvtColor(frame, gray, COLOR_BGR2GRAY);
equalizeHist(gray, gray);
faceCascader.detectMultiScale(gray, faces,1.2, 3, 0, Size(30, 30));
for (int i = 0; i < faces.size(); i++)
{
Rect roi;
roi.x = faces[static_cast<int>(i)].x;
roi.y = faces[static_cast<int>(i)].y;
roi.width = faces[static_cast<int>(i)].width;
roi.height = faces[static_cast<int>(i)].height /2.0;
Mat faceROI = frame(roi);
eyeCascader.detectMultiScale(faceROI, eyes,1.2, 3, 0, Size(20, 20));
for (int j = 0; j < eyes.size(); j++)
{
Rect rect;
rect.x = faces[static_cast<int>(i)].x + eyes[j].x + eyes[j].width/2.0;
rect.y = faces[static_cast<int>(i)].y + eyes[j].y + eyes[j].height/2.0;
rect.width = eyes[j].width;
rect.height = eyes[j].height;
circle(frame, Point(rect.x, rect.y), rect.width/2.0, Scalar(0,0,255), 2, 8);
//pt.push_back(Point(rect.x,rect.y));
}
rectangle(frame, faces[static_cast<int>(i)], Scalar(0,255,0), 2, 8, 0);
}
char q = waitKey(10);
//Esc退出
if (q == 27)
{
break;
}
/*
//绘制眼睛轨迹
for(int i=0;i<pt.size()-1;i++)
{
line(frame,pt[i],pt[i+1],Scalar(0,255,255),2.5);
}
//按c键清除绘制的眼睛轨迹
if (q == 99)
{
pt.clear();
frame = src;
}
*/
imshow("input", frame);
}
waitKey(0);
capture.release();
return 0;
}
猫脸检测
#include<opencv2/opencv.hpp>
using namespace cv;
int main()
{
CascadeClassifier haarfaceCascader;
String catfile = "D:/opencv3.1.0/opencv/tools/opencv_contrib/install/etc/haarcascades/haarcascade_frontalcatface_extended.xml";
Mat src = imread("E:/image/image/cat.jpg");
Mat gray;
std::vector<Rect> faces;
cvtColor(src, gray, COLOR_BGR2GRAY);
equalizeHist(gray, gray);
if (!haarfaceCascader.load(catfile))
{
printf("can not load the haar file \n");
return -1;
}
haarfaceCascader.detectMultiScale(gray, faces, 1.1, 3, 0, Size(30, 30), Size(300, 300));
for (int i = 0; i < faces.size(); i++)
{
rectangle(src, faces[i], Scalar(0,255,0), 2, 8, 0);
}
namedWindow("input", WINDOW_NORMAL);
imshow("input",src);
waitKey(0);
return 0;
}
HAAR与LBP区别
HAAR与LBP区别:
① HAAR特征是浮点数计算,LBP特征是整数计算;
② LBP训练需要的样本数量比HAAR大;
③ LBP的速度一般比HAAR快;
④ 同样的样本HAAR训练出来的检测结果要比LBP准确;
⑤ 扩大LBP的样本数据可达到HAAR的训练效果。
对比二者用时:
#include<opencv2/opencv.hpp>
using namespace cv;
int main()
{
CascadeClassifier haarfaceCascader, lbpfaceCascader;
String haarfile = "D:/opencv3.1.0/opencv/tools/opencv_contrib/install/etc/haarcascades/haarcascade_frontalface_alt.xml";
String lbpfile = "D:/opencv3.1.0/opencv/tools/opencv_contrib/install/etc/lbpcascades/lbpcascade_frontalface.xml";
Mat src = imread("E:/image/image/sophie.jpg");
Mat gray;
std::vector<Rect> faces1, faces2;
cvtColor(src, gray, COLOR_BGR2GRAY);
equalizeHist(gray, gray);
int st1 = getTickCount();
if (!haarfaceCascader.load(haarfile))
{
printf("can not load the haar file \n");
return -1;
}
haarfaceCascader.detectMultiScale(gray, faces1, 1.1, 3, 0, Size(30, 30));
int et1 = (getTickCount() - st1);
printf("Time to load the haar file is : %d \n", et1);
int st2 = getTickCount();
if (!lbpfaceCascader.load(lbpfile))
{
printf("can not load the lbp file \n");
return -1;
}
lbpfaceCascader.detectMultiScale(gray, faces2, 1.1, 3, 0, Size(30, 30));
int et2 = (getTickCount() - st2);
printf("Time to load the lbp file is : %d \n", et2);
for (int i = 0; i < faces1.size(); i++)
{
rectangle(src, faces1[i], Scalar(0,255,0), 2, 8, 0);
}
for (int i = 0; i < faces2.size(); i++)
{
rectangle(src, faces2[i], Scalar(0,0,255), 4, 8, 0);
}
namedWindow("input", WINDOW_AUTOSIZE);
imshow("input",src);
waitKey(0);
return 0;
}
opencv3/Python
人脸以及眼睛识别:
#!/usr/bin/python
# coding:utf8
import cv2
face_xml = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
face_xml.load('haarcascade_frontalface_default.xml')
eye_xml = cv2.CascadeClassifier('haarcascade_eye.xml')
eye_xml.load('haarcascade_eye.xml')
if __name__ == '__main__':
cam = cv2.VideoCapture(0)
# cam = cv2.VideoCapture('broke_girls.mp4')
# 获得码率及尺寸
fps = cam.get(cv2.CAP_PROP_FPS)
size = (int(cam.get(cv2.CAP_PROP_FRAME_WIDTH)), int(cam.get(cv2.CAP_PROP_FRAME_HEIGHT)))
while True:
ret, frame = cam.read()
# print ()
if ret is True:
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
else:
print ('can not read the frame \n')
break
faces = face_xml.detectMultiScale(gray, 1.3, 5)
print ('face=', len(faces))
#框选检测到的人脸,获得人脸所在区域
for (x, y, w, h) in faces:
cv2.rectangle(frame, (x, y), (x + w, y + h), (255, 0, 0), 2)
roi_face = gray[y:y + h, x:x + w]
roi = frame[y:y + h, x:x + w]
eyes = eye_xml.detectMultiScale(roi_face)
for (x_, y_, w_, h_) in eyes:
cv2.rectangle(roi, (x_, y_), (x_ + w_, y_ + h_), (0, 255, 125), 2)
cv2.imshow('image', frame)
ch = cv2.waitKey(1000/int(fps))
if ch == 27:
break
cv2.destroyAllWindows()