zoukankan      html  css  js  c++  java
  • 基于opencv的人脸识别程序

    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] = '';
    151                     cout << "file " << buf << endl;
    152                     image = imread( buf, 1 );
    153                     if( !image.empty() )
    154                     {
    155                         detectAndDraw( image, cascade, nestedCascade, scale, tryflip );
    156                         c = waitKey(0);
    157                         if( c == 27 || c == 'q' || c == 'Q' )
    158                             break;
    159                     }
    160                     else
    161                     {
    162                         cerr << "Aw snap, couldn't read image " << buf << endl;
    163                     }
    164                 }
    165                 fclose(f);
    166             }
    167         }
    168     }
    169 
    170     return 0;
    171 }
    172 
    173 void detectAndDraw( Mat& img, CascadeClassifier& cascade,
    174                     CascadeClassifier& nestedCascade,
    175                     double scale, bool tryflip )
    176 {
    177     double t = 0;
    178     vector<Rect> faces, faces2;
    179     const static Scalar colors[] =
    180     {
    181         Scalar(255,0,0),
    182         Scalar(255,128,0),
    183         Scalar(255,255,0),
    184         Scalar(0,255,0),
    185         Scalar(0,128,255),
    186         Scalar(0,255,255),
    187         Scalar(0,0,255),
    188         Scalar(255,0,255)
    189     };
    190     Mat gray, smallImg;
    191 
    192     cvtColor( img, gray, COLOR_BGR2GRAY );
    193     double fx = 1 / scale;
    194     resize( gray, smallImg, Size(), fx, fx, INTER_LINEAR );
    195     equalizeHist( smallImg, smallImg );
    196 
    197     t = (double)cvGetTickCount();
    198     cascade.detectMultiScale( smallImg, faces,
    199         1.1, 2, 0
    200         //|CASCADE_FIND_BIGGEST_OBJECT
    201         //|CASCADE_DO_ROUGH_SEARCH
    202         |CASCADE_SCALE_IMAGE,
    203         Size(30, 30) );
    204     if( tryflip )
    205     {
    206         flip(smallImg, smallImg, 1);
    207         cascade.detectMultiScale( smallImg, faces2,
    208                                  1.1, 2, 0
    209                                  //|CASCADE_FIND_BIGGEST_OBJECT
    210                                  //|CASCADE_DO_ROUGH_SEARCH
    211                                  |CASCADE_SCALE_IMAGE,
    212                                  Size(30, 30) );
    213         for( vector<Rect>::const_iterator r = faces2.begin(); r != faces2.end(); r++ )
    214         {
    215             faces.push_back(Rect(smallImg.cols - r->x - r->width, r->y, r->width, r->height));
    216         }
    217     }
    218     t = (double)cvGetTickCount() - t;
    219     printf( "detection time = %g ms
    ", t/((double)cvGetTickFrequency()*1000.) );
    220     for ( size_t i = 0; i < faces.size(); i++ )
    221     {
    222         Rect r = faces[i];
    223         Mat smallImgROI;
    224         vector<Rect> nestedObjects;
    225         Point center;
    226         Scalar color = colors[i%8];
    227         int radius;
    228 
    229         double aspect_ratio = (double)r.width/r.height;
    230         if( 0.75 < aspect_ratio && aspect_ratio < 1.3 )
    231         {
    232             center.x = cvRound((r.x + r.width*0.5)*scale);
    233             center.y = cvRound((r.y + r.height*0.5)*scale);
    234             radius = cvRound((r.width + r.height)*0.25*scale);
    235             circle( img, center, radius, color, 3, 8, 0 );
    236         }
    237         else
    238             rectangle( img, cvPoint(cvRound(r.x*scale), cvRound(r.y*scale)),
    239                        cvPoint(cvRound((r.x + r.width-1)*scale), cvRound((r.y + r.height-1)*scale)),
    240                        color, 3, 8, 0);
    241         if( nestedCascade.empty() )
    242             continue;
    243         smallImgROI = smallImg( r );
    244         nestedCascade.detectMultiScale( smallImgROI, nestedObjects,
    245             1.1, 2, 0
    246             //|CASCADE_FIND_BIGGEST_OBJECT
    247             //|CASCADE_DO_ROUGH_SEARCH
    248             //|CASCADE_DO_CANNY_PRUNING
    249             |CASCADE_SCALE_IMAGE,
    250             Size(30, 30) );
    251         for ( size_t j = 0; j < nestedObjects.size(); j++ )
    252         {
    253             Rect nr = nestedObjects[j];
    254             center.x = cvRound((r.x + nr.x + nr.width*0.5)*scale);
    255             center.y = cvRound((r.y + nr.y + nr.height*0.5)*scale);
    256             radius = cvRound((nr.width + nr.height)*0.25*scale);
    257             circle( img, center, radius, color, 3, 8, 0 );
    258         }
    259     }
    260     imshow( "result", img );
    261 }
    View Code

    问题未解决:

    运行到capture>>frame;时出现select timeout的错误;

    @ 操作系统:windows 10

    OpenCV版本:3.1.0

    代码与Linux版本基本相同,未出现错误;

  • 相关阅读:
    数据库连接池
    一致性hash
    java 集合大家族
    linkedlist
    HashMap
    hashcode
    Job 逻辑执行图
    CDN
    网站缓存
    Mysql临时文件目录控制
  • 原文地址:https://www.cnblogs.com/tanfy/p/5552270.html
Copyright © 2011-2022 走看看