1. 解析opencv自带人脸识别源码(……/opencv-3.1.0/samples/cpp/facedetect.cpp)
@ 操作系统:Ubuntu 15.04
OpenCV版本:3.1.0

1 #include "opencv2/objdetect.hpp" 2 #include "opencv2/highgui.hpp" 3 #include "opencv2/imgproc.hpp" 4 #include <iostream> 5 6 using namespace std; 7 using namespace cv; 8 9 static void help() 10 { 11 cout << " This program demonstrates the cascade recognizer. Now you can use Haar or LBP features. " 12 "This classifier can recognize many kinds of rigid objects, once the appropriate classifier is trained. " 13 "It's most known use is for faces. " 14 "Usage: " 15 "./facedetect [--cascade=<cascade_path> this is the primary trained classifier such as frontal face] " 16 " [--nested-cascade[=nested_cascade_path this an optional secondary classifier such as eyes]] " 17 " [--scale=<image scale greater or equal to 1, try 1.3 for example>] " 18 " [--try-flip] " 19 " [filename|camera_index] " 20 "see facedetect.cmd for one call: " 21 "./facedetect --cascade="../../data/haarcascades/haarcascade_frontalface_alt.xml" --nested-cascade="../../data/haarcascades/haarcascade_eye_tree_eyeglasses.xml" --scale=1.3 " 22 "During execution: Hit any key to quit. " 23 " Using OpenCV version " << CV_VERSION << " " << endl; 24 } 25 26 void detectAndDraw( Mat& img, CascadeClassifier& cascade, 27 CascadeClassifier& nestedCascade, 28 double scale, bool tryflip ); 29 30 string cascadeName; 31 string nestedCascadeName; 32 33 int main( int argc, const char** argv ) 34 { 35 VideoCapture capture; 36 Mat frame, image; 37 string inputName; 38 bool tryflip; 39 40 // CascadeClassifier是Opencv中做人脸检测的时候的一个级联分类器,现在有两种选择:一是使用老版本的CvHaarClassifierCascade函数,一是使用新版本的CascadeClassifier类。老版本的分类器只支持类Haar特征,而新版本的分类器既可以使用Haar,也可以使用LBP特征。 41 CascadeClassifier cascade, nestedCascade; 42 double scale; 43 44 cv::CommandLineParser parser(argc, argv, 45 "{help h||}" 46 "{cascade|../../data/haarcascades/haarcascade_frontalface_alt.xml|}" 47 "{nested-cascade|../../data/haarcascades/haarcascade_eye_tree_eyeglasses.xml|}" 48 "{scale|1|}{try-flip||}{@filename||}" 49 ); 50 if (parser.has("help")) 51 { 52 help(); 53 return 0; 54 } 55 56 // 问题1:不用定义返回类型? 57 cascadeName = parser.get<string>("cascade"); 58 nestedCascadeName = parser.get<string>("nested-cascade"); 59 scale = parser.get<double>("scale"); 60 if (scale < 1) 61 scale = 1; 62 tryflip = parser.has("try-flip"); 63 inputName = parser.get<string>("@filename"); 64 std::cout << inputName << std::endl; // test 65 if (!parser.check()) 66 { 67 parser.printErrors(); 68 return 0; 69 } 70 71 // 加载模型 72 if ( !nestedCascade.load( nestedCascadeName ) ) 73 cerr << "WARNING: Could not load classifier cascade for nested objects" << endl; 74 if( !cascade.load( cascadeName ) ) 75 { 76 cerr << "ERROR: Could not load classifier cascade" << endl; 77 help(); 78 return -1; 79 } 80 // 读取摄像头 81 // isdigit检测字符是否为阿拉伯数字 82 if( inputName.empty() || (isdigit(inputName[0]) && inputName.size() == 1) ) 83 { 84 int c = inputName.empty() ? 0 : inputName[0] - '0'; 85 // 此处若系统在虚拟机上,需在虚拟机中设置接管摄像头:虚拟机(M)-> 可移动设备 -> 摄像头名称 -> 连接(断开与主机连接) 86 if(!capture.open(c)) 87 cout << "Capture from camera #" << c << " didn't work" << endl; 88 else { 89 capture.set(CV_CAP_PROP_FRAME_WIDTH, 640); 90 capture.set(CV_CAP_PROP_FRAME_HEIGHT, 480); 91 } 92 } 93 else if( inputName.size() ) 94 { 95 image = imread( inputName, 1 ); 96 if( image.empty() ) 97 { 98 if(!capture.open( inputName )) 99 cout << "Could not read " << inputName << endl; 100 } 101 } 102 else 103 { 104 image = imread( "../data/lena.jpg", 1 ); 105 if(image.empty()) cout << "Couldn't read ../data/lena.jpg" << endl; 106 } 107 108 if( capture.isOpened() ) 109 { 110 cout << "Video capturing has been started ..." << endl; 111 112 113 for(;;) 114 { 115 std::cout << "capturing..." << std::endl; // test 116 capture >> frame; 117 if( frame.empty() ) 118 break; 119 120 Mat frame1 = frame.clone(); 121 std::cout << "Start to detect..." << std::endl; // test 122 detectAndDraw( frame1, cascade, nestedCascade, scale, tryflip ); 123 124 int c = waitKey(10); 125 if( c == 27 || c == 'q' || c == 'Q' ) 126 break; 127 } 128 } 129 else 130 { 131 cout << "Detecting face(s) in " << inputName << endl; 132 if( !image.empty() ) 133 { 134 detectAndDraw( image, cascade, nestedCascade, scale, tryflip ); 135 waitKey(0); 136 } 137 else if( !inputName.empty() ) 138 { 139 /* assume it is a text file containing the 140 list of the image filenames to be processed - one per line */ 141 FILE* f = fopen( inputName.c_str(), "rt" ); 142 if( f ) 143 { 144 char buf[1000+1]; 145 while( fgets( buf, 1000, f ) ) 146 { 147 int len = (int)strlen(buf), c; 148 while( len > 0 && isspace(buf[len-1]) ) 149 len--; 150 buf[len] = '