1. 解析opencv自带人脸识别源码(……/opencv-3.1.0/samples/cpp/facedetect.cpp)@ 操作系统:Ubuntu 15.04OpenCV版本:3.1.0#include "opencv2/objdetect.hpp" #include "opencv2/highgui.hpp" #include "opencv2/imgproc.hpp" #include <iostream>using namespace std; using namespace cv;static void help() { cout << "
This program demonstrates the cascade recognizer. Now you can use Haar or LBP features.
" "This classifier can recognize many kinds of rigid objects, once the appropriate classifier is trained.
" "It"s most known use is for faces.
" "Usage:
" "./facedetect [--cascade=<cascade_path> this is the primary trained classifier such as frontal face]
" " [--nested-cascade[=nested_cascade_path this an optional secondary classifier such as eyes]]
" " [--scale=<image scale greater or equal to 1, try 1.3 for example>]
" " [--try-flip]
" " [filename|camera_index]
" "see facedetect.cmd for one call:
" "./facedetect --cascade="../../data/haarcascades/haarcascade_frontalface_alt.xml" --nested-cascade="../../data/haarcascades/haarcascade_eye_tree_eyeglasses.xml" --scale=1.3
" "During execution:
Hit any key to quit.
" " Using OpenCV version " << CV_VERSION << "
" << 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|../../data/haarcascades/haarcascade_frontalface_alt.xml|}" "{nested-cascade|../../data/haarcascades/haarcascade_eye_tree_eyeglasses.xml|}" "{scale|1|}{try-flip||}{@filename||}" ); if (parser.has("help")) { help(); return 0; } // 问题1:不用定义返回类型? cascadeName = 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] = " "; 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
", 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 ); }问题未解决:运行到capture>>frame;时出现select timeout的错误;@ 操作系统:Windows 10OpenCV版本:3.1.0代码与Linux版本基本相同,未出现错误;OpenCV官方教程中文版(For Python) PDF http://www.linuxidc.com/Linux/2015-08/121400.htmUbuntu Linux下安装OpenCV2.4.1所需包 http://www.linuxidc.com/Linux/2012-08/68184.htmUbuntu 16.04上用CMake图形界面交叉编译树莓派的OpenCV3.0 http://www.linuxidc.com/Linux/2016-10/135914.htmUbuntu 12.04下安装OpenCV 2.4.5总结 http://www.linuxidc.com/Linux/2013-06/86704.htmUbuntu 10.04中安装OpenCv2.1九步曲 http://www.linuxidc.com/Linux/2010-09/28678.htm基于QT和OpenCV的人脸识别系统 http://www.linuxidc.com/Linux/2011-11/47806.htm[翻译]Ubuntu 14.04, 13.10 下安装 OpenCV 2.4.9 http://www.linuxidc.com/Linux/2014-12/110045.htmOpenCV的详细介绍:请点这里 OpenCV的下载地址:请点这里本文永久更新链接地址:http://www.linuxidc.com/Linux/2016-11/137099.htm