前段时间看的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: ranjiewen@outlook.com
* \问题描述:
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...

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

  1. OpenCV + python 实现人脸检测(基于照片和视频进行检测)

    OpenCV + python 实现人脸检测(基于照片和视频进行检测) Haar-like 通俗的来讲,就是作为人脸特征即可. Haar特征值反映了图像的灰度变化情况.例如:脸部的一些特征能由矩形特征 ...

  2. OpenCV入门指南----人脸检测

    本篇介绍图像处理与模式识别中最热门的一个领域——人脸检测(人脸识别).人脸检测可以说是学术界的宠儿,在不少EI,SCI高级别论文都能看到它的身影.甚至很多高校学生的毕业设计都会涉及到人脸检测.当然人脸 ...

  3. opencv 美白磨皮人脸检测<转>

    1. 简介 这学期的计算机视觉课,我们组的课程项目为“照片自动美化”,其中我负责的模块为人脸检测与自动磨皮.功能为:用户上传一张照片,自动检测并定位出照片中的人脸,将照片中所有的人脸进行“磨皮”处理, ...

  4. Android 中使用 dlib+opencv 实现动态人脸检测

    1 概述 完成 Android 相机预览功能以后,在此基础上我使用 dlib 与 opencv 库做了一个关于人脸检测的 demo.该 demo 在相机预览过程中对人脸进行实时检测,并将检测到的人脸用 ...

  5. OpenCV神技——人脸检测,猫脸检测

    简介   OpenCV是一个基于BSD许可(开源)发行的跨平台计算机视觉库,可以运行在Linux.Windows.Android和Mac OS操作系统上.它轻量级而且高效--由一系列 C 函数和少量 ...

  6. Android—基于OpenCV+Android实现人脸检测

    导读 OpenCV 是一个开源的跨平台计算机视觉库, 采C++语言编写,实现了图像处理和计算机视觉方面的很多通用算法,同时也提供对Python,Java,Android等的支持,这里利用Android ...

  7. 手把手教你如何用 OpenCV + Python 实现人脸检测

    配好了OpenCV的Python环境,OpenCV的Python环境搭建.于是迫不及待的想体验一下opencv的人脸识别,如下文. 必备知识 Haar-like Haar-like百科释义.通俗的来讲 ...

  8. opencv+python实时人脸检测、磨皮

    import numpy as np import cv2 cap = cv2.VideoCapture(0) face_cascade = cv2.CascadeClassifier("d ...

  9. 【转载】opencv实现人脸检测

    全文转载自CSDN的博客(不知道怎么将CSDN的博客转到博客园,应该没这功能吧,所以直接复制全文了),转载地址如下 http://blog.csdn.net/lsq2902101015/article ...

随机推荐

  1. 构建CMDB的一些启发

    开篇感言: 自从学习python自动化开发以来,一直都是从技术的角度来看待一切.以为技术就是王道.但显然我是一只井底之蛙.其实技术只不过是实现功能的工具而已,仅此而已.后来学习了解CMDB,越来越发现 ...

  2. 初级程序员应该了解的Linux命令

    基于Linux的系统最美妙的一点,就是你可以在终端中使用命令行来管理整个系统.使用命令行的优势在于,你可以使用相同的知识和技能来管理随便哪个Linux发行版. 对于各个发行版以及桌面环境(DE)而言, ...

  3. LINUX下mysql的大小写是否区分设置 转

    一.Linux中MySQL大小写详情:1.数据库名严格区分大小写2.表名严格区分大小写的3.表的别名严格区分大小写4.变量名严格区分大小写5.列名在所有的情况下均忽略大小写6.列的别名在所有的情况下均 ...

  4. ROS学习笔记(九)——ROSSERVICE

    NEW 1 $ roscore NEW 2 $ rosrun turtlesim turtlesim_node NEW 3 $ rosrun turtlesim turtle_teleop_key N ...

  5. (3/18)重学Standford_iOS7开发_Objective-C_课程笔记

    第三课: 本节课主要是游戏实现的demo,因此我将把课程中简单的几个编程技巧提取出来,重点介绍如何自己实现作业中的要求. 纸牌游戏实现: ①游戏的进行是模型的一部分(理解什么是模型:Model = W ...

  6. 在C#中如何确定一个文件是不是文本文件,以及如何确定一个文件的类型

    博客搬到了fresky.github.io - Dawei XU,请各位看官挪步.最新的一篇是:在C#中如何确定一个文件是不是文本文件,以及如何确定一个文件的类型.

  7. load 与initialize的调用顺序小结

    开发中实用方法固然是最贴近应用的,当一些程序原理还是要先搞清晰,根据查找的一些资料,总结了一些load与initialize的调用. APP启动到执行main函数之前,程序就执行了很多代码   执行顺 ...

  8. hdu 4523 威威猫系列故事——过生日 小模拟

    威威猫系列故事——过生日 Time Limit: 500/200 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others) Total ...

  9. win7下jdk安装环境变量配置

    新本本,新系统,还是得把武器给装配好. 以下图文记录win7系统下的jdk的安装和配置. 1.下载jdk 地址:http://java.sun.com/javase/downloads/index.j ...

  10. Android获取设备隐私 忽略6.0权限管理

    1.前言 (1).由于MIUI等部分国产定制系统也有权限管理,没有相关api,故无法判断用户是否允许获取联系人等隐私.在Android 6.0之后,新增权限管理可以通过官方api判断用户的运行状态: ...