OpenCV例程实现人脸检测

前段时间看的OpenCV,其实有很多的例子程序,参考代码值得我们学习,对图像特征提取三大法宝:HOG特征,LBP特征,Haar特征有一定了解后。

对本文中的例子程序刚开始没有调通,今晚上调通了,试了试效果还可以,还需要深入理解。值得大家动手试试,还是很有成就感的,虽然是现成的例子.......

环境:OpenCV3.1+VS2013+WIN10

复制代码
/*!
* \file Capture.cpp
*
* \author ranjiewen
* \date 十一月 2016
*
* http://www.cnblogs.com/tanfy/p/5552270.html

解析opencv自带人脸识别源码(……/opencv-3.1.0/samples/cpp/facedetect.cpp)
*/
#include "opencv2/objdetect.hpp"
#include "opencv2/highgui.hpp"
#include "opencv2/imgproc.hpp"
#include <iostream>

using namespace std;
using namespace cv;

static void help()
{
cout << "\nThis program demonstrates the cascade recognizer. Now you can use Haar or LBP features.\n"
"This classifier can recognize many kinds of rigid objects, once the appropriate classifier is trained.\n"
"It‘s most known use is for fawww.ymzxrj.com 直销软件
www.yyzx66.cn/ ces.\n"
"Usage:\n"
"./facedetect [--cascade=<cascade_path> this is the primary trained classifier such as frontal face]\n"
" [--nested-cascade[=nested_cascade_path this an optional secondary classifier such as eyes]]\n"
" [--scale=<image scale greater or www.ymzxrj.com equal to 1, try 1.3 for example>]\n"
" [--try-flip]\n"
" [filename|camera_index]\n\n"
"see facedetect.cmd for one call:\n"
"./facedetect --cascade=\"../../data/haarcascades/haarcascade_frontalface_alt.xml\" --nested-cascade=\"../../data/haarcascades/haarcascade_ewww.yunfeizao.cn 菲云国际
www.feiyunfan.cn ye_tree_eyeglasses.xml\" --scale=1.3\n\n"
"During execution:\n\tHit any key to quit.\n"
"\tUsing OpenCV version " << CV_VERSION << "\n" << endl;
}

void detectAndDraw(Mat& img, CascadeClassifier& cascade,
CascadeClassifier& nestedCascade,
double scale, bool tryflip);

string cascadeName;
string nestedCascadeName;

int main(int argc, const char** argv)
{
VideoCapture capture;
Mat frame, image;
string inputName;
bool tryflip;

// CascadeClassifier是Opencv中做人脸检测的时候的一个级联分类器,现在有两种选择:一是使用老版本的CvHaarClassifierCascade函数,一是使用新版本的CascadeClassifier类。老版本的分类器只支持类Haar特征,而新版本的分类器既可以使用Haar,也可以使用LBP特征。
CascadeClassifier cascade, nestedCascade;
double scale;

cv::CommandLineParser parser(argc, argv,
"{help h||}"
"{cascade|D:/opencv/sources/data/haarcascades/haarcascade_frontalface_alt.xml|}" //默认路径实在安装路径下sample,修改了路径,以便加载load成功
"{nested-cascade|D:/opencv/sources/data/haarcascades/haarcascade_eye_tree_eyeglasses.xml|}" //修改路径
"{scale|1|}{try-flip||}www.fsmaxbuy.com/ {@filename||}" //文件为空时,设置摄像头,实时检测人脸
);
if (parser.has("help"))
{
help();
return 0;
}

cascadeName = www.yiqianou.cn/ parser.get<string>("cascade");
nestedCascadeName = parser.get<string>("nested-cascade");
scale = parser.get<double>("scale");
if (scale < 1)
scale = 1;
tryflip = parser.has("try-flip");
inputName = parser.get<string>("@filename");
std::cout << inputName << std::endl; // test
if (!parser.check())
{
parser.printErrors();
return 0;
}

// 加载模型
if (!nestedCascade.load(nestedCascadeName))
cerr << "WARNING: Could not load classifier cascade for nested objects" << endl;
if (!cascade.load(cascadeName))
{
cerr << "ERROR: Could not load classifier cascade" << endl;
help();
return -1;
}
// 读取摄像头
// isdigit检测字符是否为阿拉伯数字
if (inputName.empty() || (isdigit(inputName[0]) && inputName.size() == 1))
{
int c = inputName.empty() ? 0 : inputName[0] - ‘0‘;
// 此处若系统在虚拟机上,需在虚拟机中设置接管摄像头:虚拟机(M)-> 可移动设备 -> 摄像头名称 -> 连接(断开与主机连接)
if (!capture.open(c))
cout << "Capture from camera #" << c << " didn‘t work" << endl;
else {
capture.set(CV_CAP_PROP_FRAME_WIDTH, 640);
capture.set(CV_CAP_PROP_FRAME_HEIGHT, 480);
}
}
else if (inputName.size())
{
image = imread(inputName, 1);
if (image.empty())
{
if (!capture.open(inputName))
cout << "Could not read " << inputName << endl;
}
}
else
{
image = imread("../data/lena.jpg", 1);
if (image.empty()) cout << "Couldn‘t read ../data/lena.jpg" << endl;
}

if (capture.isOpened())
{
cout << "Video capturing has been started ..." << endl;

for (;;)
{
std::cout << "capturing..." << std::endl; // test
capture >> frame;
if (frame.empty())
break;

Mat frame1 = frame.clone();
std::cout << "Start to detect..." << std::endl; // test
detectAndDraw(frame1, cascade, nestedCascade, scale, tryflip);

int c = waitKey(10);
if (c == 27 || c == ‘q‘ || c == ‘Q‘)
break;
}
}
else
{
cout << "Detecting face(s) in " << inputName << endl;
if (!image.empty())
{
detectAndDraw(image, cascade, nestedCascade, scale, tryflip);
waitKey(0);
}
else if (!inputName.empty())
{
/* assume it is a text file containing the
list of the image filenames to be processed - one per line */
FILE* f = fopen(inputName.c_str(), "rt");
if (f)
{
char buf[1000 + 1];
while (fgets(buf, 1000, f))
{
int len = (int)strlen(buf), c;
while (len > 0 && isspace(buf[len - 1]))
len--;
buf[len] = ‘\0‘;
cout << "file " << buf << endl;
image = imread(buf, 1);
if (!image.empty())
{
detectAndDraw(image, cascade, nestedCascade, scale, tryflip);
c = waitKey(0);
if (c == 27 || c == ‘q‘ || c == ‘Q‘)
break;
}
else
{
cerr << "Aw snap, couldn‘t read image " << buf << endl;
}
}
fclose(f);
}
}
}

return 0;
}

void detectAndDraw(Mat& img, CascadeClassifier& cascade,
CascadeClassifier& nestedCascade,
double scale, bool tryflip)
{
double t = 0;
vector<Rect> faces, faces2;
const static Scalar colors[] =
{
Scalar(255, 0, 0),
Scalar(255, 128, 0),
Scalar(255, 255, 0),
Scalar(0, 255, 0),
Scalar(0, 128, 255),
Scalar(0, 255, 255),
Scalar(0, 0, 255),
Scalar(255, 0, 255)
};
Mat gray, smallImg;

cvtColor(img, gray, COLOR_BGR2GRAY);
double fx = 1 / scale;
resize(gray, smallImg, Size(), fx, fx, INTER_LINEAR);
equalizeHist(smallImg, smallImg);

t = (double)cvGetTickCount();
cascade.detectMultiScale(smallImg, faces,
1.1, 2, 0
//|CASCADE_FIND_BIGGEST_OBJECT
//|CASCADE_DO_ROUGH_SEARCH
| CASCADE_SCALE_IMAGE,
Size(30, 30));
if (tryflip)
{
flip(smallImg, smallImg, 1);
cascade.detectMultiScale(smallImg, faces2,
1.1, 2, 0
//|CASCADE_FIND_BIGGEST_OBJECT
//|CASCADE_DO_ROUGH_SEARCH
| CASCADE_SCALE_IMAGE,
Size(30, 30));
for (vector<Rect>::const_iterator r = faces2.begin(); r != faces2.end(); r++)
{
faces.push_back(Rect(smallImg.cols - r->x - r->width, r->y, r->width, r->height));
}
}
t = (double)cvGetTickCount() - t;
printf("detection time = %g ms\n", t / ((double)cvGetTickFrequency()*1000.));
for (size_t i = 0; i < faces.size(); i++)
{
Rect r = faces[i];
Mat smallImgROI;
vector<Rect> nestedObjects;
Point center;
Scalar color = colors[i % 8];
int radius;

double aspect_ratio = (double)r.width / r.height;
if (0.75 < aspect_ratio && aspect_ratio < 1.3)
{
center.x = cvRound((r.x + r.width*0.5)*scale);
center.y = cvRound((r.y + r.height*0.5)*scale);
radius = cvRound((r.width + r.height)*0.25*scale);
circle(img, center, radius, color, 3, 8, 0);
}
else
rectangle(img, cvPoint(cvRound(r.x*scale), cvRound(r.y*scale)),
cvPoint(cvRound((r.x + r.width - 1)*scale), cvRound((r.y + r.height - 1)*scale)),
color, 3, 8, 0);
if (nestedCascade.empty())
continue;
smallImgROI = smallImg(r);
nestedCascade.detectMultiScale(smallImgROI, nestedObjects,
1.1, 2, 0
//|CASCADE_FIND_BIGGEST_OBJECT
//|CASCADE_DO_ROUGH_SEARCH
//|CASCADE_DO_CANNY_PRUNING
| CASCADE_SCALE_IMAGE,
Size(30, 30));
for (size_t j = 0; j < nestedObjects.size(); j++)
{
Rect nr = nestedObjects[j];
center.x = cvRound((r.x + nr.x + nr.width*0.5)*scale);
center.y = cvRound((r.y + nr.y + nr.height*0.5)*scale);
radius = cvRound((nr.width + nr.height)*0.25*scale);
circle(img, center, radius, color, 3, 8, 0);
}
}
imshow("result", img);
}

/*****************************************************
* \file Capture.cpp
* \date 2016/11/10 0:22
* \author ranjiewen
* \contact: [email protected]
* \问题描述:
http://www.cnblogs.com/lingshaohu/archive/2011/12/16/2290017.html

* \问题分析:
可以存avi,但是不能打开,待改善
*****************************************************/

//#include <iostream>
//#include <opencv2/opencv.hpp>
//using namespace cv;;
//using namespace std;
//int main()
//{
// CvCapture* capture = cvCaptureFromCAM(-1);
// CvVideoWriter* video = NULL;
// IplImage* frame = NULL;
// int n;
// if (!capture) //如果不能打开摄像头给出警告
// {
// cout << "Can not open the camera." << endl;
// return -1;
// }
// else
// {
// frame = cvQueryFrame(capture); //首先取得摄像头中的一帧
// video = cvCreateVideoWriter("camera.avi", CV_FOURCC(‘X‘, ‘V‘, ‘I‘, ‘D‘), 25,
// cvSize(frame->width, frame->height)); //创建CvVideoWriter对象并分配空间
// //保存的文件名为camera.avi,编码要在运行程序时选择,大小就是摄像头视频的大小,帧频率是32
// if (video) //如果能创建CvVideoWriter对象则表明成功
// {
// cout << "VideoWriter has created." << endl;
// }
//
// cvNamedWindow("Camera Video", 1); //新建一个窗口
// int i = 0;
// while (i <= 300) // 让它循环200次自动停止录取
// {
// frame = cvQueryFrame(capture); //从CvCapture中获得一帧
// if (!frame)
// {
// cout << "Can not get frame from the capture." << endl;
// break;
// }
// n = cvWriteFrame(video, frame); //判断是否写入成功,如果返回的是1,表示写入成功
// cout << n << endl;
// cvShowImage("Camera Video", frame); //显示视频内容的图片
// i++;
// if (cvWaitKey(2) > 0)
// break; //有其他键盘响应,则退出
// }
//
// cvReleaseVideoWriter(&video);
// cvReleaseCapture(&capture);
// cvDestroyWindow("Camera Video");
// }
// return 0;
//}
复制代码
这是调用摄像头动态检测人脸的程序,实验结果:

控制台输出:

复制代码
***** VIDEOINPUT LIBRARY - 0.1995 - TFW07 *****

SETUP: Setting up device 0
SETUP: Integrated Camera
SETUP: Couldn‘t find preview pin using SmartTee
SETUP: Default Format is set to 640x480
SETUP: trying specified format RGB24 @ 640x480
SETUP: trying format RGB24 @ 640x480
SETUP: trying format RGB32 @ 640x480
SETUP: trying format RGB555 @ 640x480
SETUP: trying format RGB565 @ 640x480
SETUP: trying format YUY2 @ 640x480
SETUP: Capture callback set
SETUP: Device is setup and ready to capture.

Video capturing has been started ...
capturing...
Start to detect...
detection time = 486.754 ms
capturing...
Start to detect...
detection time = 444.236 ms
capturing...
Start to detect...
detection time = 441.649 ms
capturing...
Start to detect...
detection time = 447.361 ms
capturing...
Start to detect...
detection time = 427.589 ms
capturing...
Start to detect...
detection time = 453.187 ms
capturing...
Start to detect...

时间: 2024-12-25 12:46:41

OpenCV例程实现人脸检测的相关文章

Opencv:视频中人脸检测并保存人脸图片

# OpenCV版本的视频检测 import cv2 # 图片识别方法封装 def discern(img): gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) cap = cv2.CascadeClassifier( "C:\Python36\Lib\site-packages\opencv-master\data\haarcascades\haarcascade_frontalface_default.xml" ) faceRects = c

【OpenCV入门指南】第十三篇 人脸检测

[OpenCV入门指南]第十三篇 人脸检测 本篇介绍图像处理与模式识别中最热门的一个领域--人脸检测(人脸识别).人脸检测可以说是学术界的宠儿,在不少EI,SCI高级别论文都能看到它的身影.甚至很多高校学生的毕业设计都会涉及到人脸检测.当然人脸检测的巨大实用价值也让很多公司纷纷关注,很多公司都拥有这方面的专利或是开发商业产品出售. 在OpenCV中,人脸检测也是其热门应用之一.在OpenCV的特征检测专题就详细介绍了人脸检测的原理--通过Haar特征来识别是否为人脸.Haar特征检测原理与Haa

OpenCV+OpenVINO实现人脸Landmarks实时检测

缘由 自从OpenCV3.3版本引入深度神经网络(DNN)模块之后,OpenCV对DNN模块支持最好的表现之一就是开始支持基于深度学习人脸检测,OpenCV本身提供了两个模型分别是基于Caffe与Tensorflow的,Caffe版本的模型是半精度16位的,tensorflow版本的模型是8位量化的.同时OpenCV通过与OpenVINO IE模型集成实现了底层硬件对对象检测.图像分割.图像分类等常见模型加速推理支持.OpenVINO框架本身提供直接快速开发应用原型的模型库,对很多常见视觉任务都

opencv-python学习一--人脸检测

简略的介绍一下 :  opencv是什么? , 人脸检测是什么? 最近对机器学习有点感兴趣,想直接从图像识别入手,这里选择了鼎鼎有名的 opencv ,一开始想直接调用opencv的api进行人脸的检测,功能也特简单,一:检测出人脸,用方框标记一下,二:输出图片中存在几个人. 在opencv的 example 中找到了已经写好的示例,示例是对一个video中的图像识别,这里做一个简化,只是检测单独的一张图片. import cv2 import sys # Get user supplied v

图片人脸检测——Dlib版(四)

上几篇给大家讲了OpenCV的图片人脸检测,而本文给大家带来的是比OpenCV更加精准的图片人脸检测Dlib库. 点击查看往期: <图片人脸检测——OpenCV版(二)> <视频人脸检测——OpenCV版(三)> dlib与OpenCV对比 识别精准度:Dlib >= OpenCV Dlib更多的人脸识别模型,可以检测脸部68甚至更多的特征点 效果展示 人脸的68个特征点 安装dlib 下载地址:https://pypi.org/simple/dlib/ 选择适合你的版本,本

视频人脸检测——Dlib版(六)

往期目录 视频人脸检测--Dlib版(六) OpenCV添加中文(五) 图片人脸检测--Dlib版(四) 视频人脸检测--OpenCV版(三) 图片人脸检测--OpenCV版(二) OpenCV环境搭建(一) 更多更新,欢迎访问我的github:https://github.com/vipstone/faceai 前言 Dlib的人脸识别要比OpenCV精准很多,一个是模型方面的差距,在一方面和OpenCV的定位有关系,OpenCV是一个综合性的视觉处理库,既然这么精准,那就一起赶快来看吧. 视

OpenCV&amp;Qt学习之四——OpenCV 实现人脸检测与相关知识整理

开发配置 OpenCV的例程中已经带有了人脸检测的例程,位置在:OpenCV\samples\facedetect.cpp文件,OpenCV的安装与这个例子的测试可以参考我之前的博文Linux 下编译安装OpenCV. 网上能够找到关于OpenCV人脸检测的例子也比较多,大多也都是基于这个例程来更改,只是多数使用的是OpenCV 1.0的版本,而OpenCV2.0以后由于模块结构的更改,很多人并没有将例程运行起来.如果是新版的OpenCV跑旧的例程,编译运行出错的话,需要确保: #include

基于Opencv的人脸检测及识别

一.实验目的:我这里完成的是,将8张人脸图片(4组,每组两张)存入库中,选取1张图片,程序识别出与其匹配的另一张. 这里介绍分三个步骤完成该工作,①程序读取摄像头.拍照 ②程序从电脑文档中读取图片   ③检测人脸,并用红框框出人脸 ④使用感知哈希算法匹配最相似的图片 二.实验环境: Win 7(x64).visual studio 2010.openCV-2.4.3 使用语言:C++ 三.实验准备:①安装好vs2010,本文不予介绍.   ②配置opencv : 1'进入官网下载http://o

OpenCV人脸检测

由于光照.遮挡和倾斜等原因,部分人脸和眼睛并不能正确检测.. // 简单的人脸检测 #include <iostream> #include <vector> #include <opencv2\opencv.hpp> #include "opencv2/objdetect/objdetect.hpp" #include "opencv2/highgui/highgui.hpp" #include "opencv2/im