概述
第一次接触计算机视觉,需要使用opencv,于是借了些资料,发现这个人脸识别的程序非常有趣,于是就加了些简单的注释,以备更深入的学习。PS:水好深啊~~~加油了。
#include "opencv2/objdetect/objdetect.hpp" //物体检测库
#include "opencv2/highgui/highgui.hpp" //图形视频处理库
#include "opencv2/imgproc/imgproc.hpp" //brief The Image Processing
#include <cctype>
#include <iostream>
#include <iterator>
#include <stdio.h>
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 faces.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 equal to 1, try 1.3 for example>]n"
" [--try-flip]n"
" [filename|camera_index]nn"
"see facedetect.cmd for one call:n"
"./facedetect --cascade="../../data/haarcascades/haarcascade_frontalface_alt.xml" --nested-cascade="../../data/haarcascades/haarcascade_eye.xml" --scale=1.3nn"
"During execution:ntHit 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 = "../../data/haarcascades/haarcascade_frontalface_alt.xml";
//string nestedCascadeName = "../../data/haarcascades/haarcascade_eye_tree_eyeglasses.xml";
string cascadeName = "haarcascade_frontalface_alt.xml"; //人脸的训练数据
//string nestedCascadeName = "haarcascade_eye_tree_eyeglasses.xml"; //人眼的训练数据
string nestedCascadeName = "haarcascade_eye.xml"; //人眼的训练数据
int main( int argc, const char** argv )
{
//参数选项定义
CvCapture* capture = 0; //视频获取结构
Mat frame, frameCopy, image; //定义矩阵
const string scaleOpt = "--scale=";
size_t scaleOptLen = scaleOpt.length();
const string cascadeOpt = "--cascade="; //级联
size_t cascadeOptLen = cascadeOpt.length();
const string nestedCascadeOpt = "--nested-cascade";
size_t nestedCascadeOptLen = nestedCascadeOpt.length();
const string tryFlipOpt = "--try-flip";
size_t tryFlipOptLen = tryFlipOpt.length();
string inputName;
bool tryflip = false;
help();
CascadeClassifier cascade, nestedCascade; //定义级联分类器对象
double scale = 1;
//一下两行代码可以删掉~~~~~
if(argc==1)
inputName="lena.jpg";
//初始化
for( int i = 1; i < argc; i++ )
{
//return 0;
cout << "Processing " << i << " " << argv[i] << endl;
waitKey(0);
if( cascadeOpt.compare( 0, cascadeOptLen, argv[i], cascadeOptLen ) == 0 )
{
cascadeName.assign( argv[i] + cascadeOptLen );
cout << " from which we have cascadeName= " << cascadeName << endl;
}
else if( nestedCascadeOpt.compare( 0, nestedCascadeOptLen, argv[i], nestedCascadeOptLen ) == 0 )
{
if( argv[i][nestedCascadeOpt.length()] == '=' )
nestedCascadeName.assign( argv[i] + nestedCascadeOpt.length() + 1 );
if( !nestedCascade.load( nestedCascadeName ) )
cerr << "WARNING: Could not load classifier cascade for nested objects" << endl;
}
else if( scaleOpt.compare( 0, scaleOptLen, argv[i], scaleOptLen ) == 0 )
{
if( !sscanf( argv[i] + scaleOpt.length(), "%lf", &scale ) || scale < 1 )
scale = 1;
cout << " from which we read scale = " << scale << endl;
}
else if( tryFlipOpt.compare( 0, tryFlipOptLen, argv[i], tryFlipOptLen ) == 0 )
{
tryflip = true;
cout << " will try to flip image horizontally to detect assymetric objectsn";
}
else if( argv[i][0] == '-' )
{
cerr << "WARNING: Unknown option %s" << argv[i] << endl;
}
else
inputName.assign( argv[i] );
}
if( !cascade.load( cascadeName ) ) //从指定的文件目录中加载人脸级联分类器
{
cerr << "ERROR: Could not load classifier cascade" << endl;
help();
return -1;
}
if(!nestedCascade.load(nestedCascadeName)) //从指定的文件目录中加载人眼级联分类器
{
cerr<<"ERROR: Could not load classifier nestedCascade"<<endl;
help();
return -1;
}
if( inputName.empty() || (isdigit(inputName.c_str()[0]) && inputName.c_str()[1] == '