2012-09-28 2 views
3

bash 스크립트 (do-something-if-picture-passed-contains-faces, else try next picture)에서 사용할 명령 줄에서 그림의 얼굴 수를 계산해야합니다.bash에서의 얼굴 인식 : 발견 된 얼굴 수를 반환하십시오.

지금까지 내가 작업 facedetectOpenCV 예를 가지고 있지만,이 예제는 지속적으로 영상을 표시합니다 - 단순히 에러 코드, 내가 원하는 것 모든 숫자가 반환 (또는 : 0 더 얼굴을 찾을 수없는 경우, 1 얼굴이 된 경우 녹이다).

슬프게도 내 C++ 기술이 심해요. 누군가 올바른 방향으로 나를 가리킬 수 있습니까?

파이썬이나 루비를 사용하고 싶지만 OpenCV 바인딩은 우분투 12.04에서 깨진 것 같습니다. 예제가 제대로 작동하지 않습니다.

감사합니다.

편집 : 내가

cat /usr/share/doc/opencv-doc/examples/c/facedetect.cpp 우분투

에서 OpenCV의 설치로 얘기했다 예 :

#include "opencv2/objdetect/objdetect.hpp" 
#include "opencv2/highgui/highgui.hpp" 
#include "opencv2/imgproc/imgproc.hpp" 

#include <iostream> 
#include <stdio.h> 

using namespace std; 
using namespace cv; 

void help() 
{ 
    cout << "\nThis program demonstrates the cascade recognizer. Now you can use Haar or LBP features.\n" 
      "This classifier can recognize many ~rigid objects, 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" 
       " [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_eye.xml\" --scale=1.3 \n" 
      "Hit any key to quit.\n" 
      "Using OpenCV version " << CV_VERSION << "\n" << endl; 
} 

void detectAndDraw(Mat& img, 
        CascadeClassifier& cascade, CascadeClassifier& nestedCascade, 
        double scale); 

String cascadeName = "../../data/haarcascades/haarcascade_frontalface_alt.xml"; 
String nestedCascadeName = "../../data/haarcascades/haarcascade_eye_tree_eyeglasses.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(); 
    String inputName; 

    help(); 

    CascadeClassifier cascade, nestedCascade; 
    double scale = 1; 

    for(int i = 1; i < argc; i++) 
    { 
     cout << "Processing " << i << " " << argv[i] << endl; 
     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(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; 
     cerr << "Usage: facedetect [--cascade=<cascade_path>]\n" 
      " [--nested-cascade[=nested_cascade_path]]\n" 
      " [--scale[=<image scale>\n" 
      " [filename|camera_index]\n" << endl ; 
     return -1; 
    } 

    if(inputName.empty() || (isdigit(inputName.c_str()[0]) && inputName.c_str()[1] == '\0')) 
    { 
     capture = cvCaptureFromCAM(inputName.empty() ? 0 : inputName.c_str()[0] - '0'); 
     int c = inputName.empty() ? 0 : inputName.c_str()[0] - '0' ; 
     if(!capture) cout << "Capture from CAM " << c << " didn't work" << endl; 
    } 
    else if(inputName.size()) 
    { 
     image = imread(inputName, 1); 
     if(image.empty()) 
     { 
      capture = cvCaptureFromAVI(inputName.c_str()); 
      if(!capture) cout << "Capture from AVI didn't work" << endl; 
     } 
    } 
    else 
    { 
     image = imread("lena.jpg", 1); 
     if(image.empty()) cout << "Couldn't read lena.jpg" << endl; 
    } 

    cvNamedWindow("result", 1); 

    if(capture) 
    { 
     cout << "In capture ..." << endl; 
     for(;;) 
     { 
      IplImage* iplImg = cvQueryFrame(capture); 
      frame = iplImg; 
      if(frame.empty()) 
       break; 
      if(iplImg->origin == IPL_ORIGIN_TL) 
       frame.copyTo(frameCopy); 
      else 
       flip(frame, frameCopy, 0); 

      detectAndDraw(frameCopy, cascade, nestedCascade, scale); 

      if(waitKey(10) >= 0) 
       goto _cleanup_; 
     } 

     waitKey(0); 

_cleanup_: 
     cvReleaseCapture(&capture); 
    } 
    else 
    { 
     cout << "In image read" << endl; 
     if(!image.empty()) 
     { 
      detectAndDraw(image, cascade, nestedCascade, scale); 
      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); 
         c = waitKey(0); 
         if(c == 27 || c == 'q' || c == 'Q') 
          break; 
        } 
        else 
        { 
         cerr << "Aw snap, couldn't read image " << buf << endl; 
        } 
       } 
       fclose(f); 
      } 
     } 
    } 

    cvDestroyWindow("result"); 

    return 0; 
} 

void detectAndDraw(Mat& img, 
        CascadeClassifier& cascade, CascadeClassifier& nestedCascade, 
        double scale) 
{ 
    int i = 0; 
    double t = 0; 
    vector<Rect> faces; 
    const static Scalar colors[] = { CV_RGB(0,0,255), 
     CV_RGB(0,128,255), 
     CV_RGB(0,255,255), 
     CV_RGB(0,255,0), 
     CV_RGB(255,128,0), 
     CV_RGB(255,255,0), 
     CV_RGB(255,0,0), 
     CV_RGB(255,0,255)} ; 
    Mat gray, smallImg(cvRound (img.rows/scale), cvRound(img.cols/scale), CV_8UC1); 

    cvtColor(img, gray, CV_BGR2GRAY); 
    resize(gray, smallImg, smallImg.size(), 0, 0, INTER_LINEAR); 
    equalizeHist(smallImg, smallImg); 

    t = (double)cvGetTickCount(); 
    cascade.detectMultiScale(smallImg, faces, 
     1.1, 2, 0 
     //|CV_HAAR_FIND_BIGGEST_OBJECT 
     //|CV_HAAR_DO_ROUGH_SEARCH 
     |CV_HAAR_SCALE_IMAGE 
     , 
     Size(30, 30)); 
    t = (double)cvGetTickCount() - t; 
    printf("detection time = %g ms\n", t/((double)cvGetTickFrequency()*1000.)); 
    for(vector<Rect>::const_iterator r = faces.begin(); r != faces.end(); r++, i++) 
    { 
     Mat smallImgROI; 
     vector<Rect> nestedObjects; 
     Point center; 
     Scalar color = colors[i%8]; 
     int radius; 
     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); 
     if(nestedCascade.empty()) 
      continue; 
     smallImgROI = smallImg(*r); 
     nestedCascade.detectMultiScale(smallImgROI, nestedObjects, 
      1.1, 2, 0 
      //|CV_HAAR_FIND_BIGGEST_OBJECT 
      //|CV_HAAR_DO_ROUGH_SEARCH 
      //|CV_HAAR_DO_CANNY_PRUNING 
      |CV_HAAR_SCALE_IMAGE 
      , 
      Size(30, 30)); 
     for(vector<Rect>::const_iterator nr = nestedObjects.begin(); nr != nestedObjects.end(); nr++) 
     { 
      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); 
     } 
    } 
    cv::imshow("result", img); 
} 
+0

실례를 게시 해주십시오. – terdon

+0

물론, 미안 해요. 여기 당신은 ... – Christian

+0

OpenCV가 자신의 답변 섹션을 가지고 있음을 알게되었을뿐입니다. [여기] (http://answers.opencv.org/question/2702/simply-count-number-of-faces /)를 참조하십시오. – Christian

답변

1
  1. 변경 void detectAndDraw
  2. int detectAndDrawint detectAndDraw에이 faces.end()-faces.begin(); 를 반환 할 것 당신은 그림 속의 얼굴 수를 얻을 수 있습니다. 도움이되기를 바랍니다.
+0

정보 주셔서 감사합니다, 나는 주말에 이것을 바로 시도 할 것입니다! – Christian