2015-05-05 55 views
0

雖然我是初學者,但我正在使用opencv和C++。我試圖使用Haarcascade從一組圖像中檢測和計數面部。 我只想獲取每張圖片上的人臉數量。 如何編輯此代碼以獲取圖像上的人臉數量?使用打開的cv和C++檢測並計算圖像上的臉部

// Function detectAndDisplay 
void detectAndDisplay(Mat frame) 
{ 
std::vector<Rect> faces; 
Mat frame_gray; 
Mat crop; 
Mat res; 
Mat gray; 
string text; 
stringstream sstm; 

cvtColor(frame, frame_gray, COLOR_BGR2GRAY); 
equalizeHist(frame_gray, frame_gray); 

// Detect faces 
face_cascade.detectMultiScale(frame_gray, faces, 1.1, 2, 0 |  CASCADE_SCALE_IMAGE, Size(30, 30)); 

// Set Region of Interest 
cv::Rect roi_b; 
cv::Rect roi_c; 

size_t ic = 0; // ic is index of current element 
int ac = 0; // ac is area of current element 

size_t ib = 0; // ib is index of biggest element 
int ab = 0; // ab is area of biggest element 

for (ic = 0; ic < faces.size(); ic++) // Iterate through all current elements (detected faces) 

{ 
    roi_c.x = faces[ic].x; 
    roi_c.y = faces[ic].y; 
    roi_c.width = (faces[ic].width); 
    roi_c.height = (faces[ic].height); 

    ac = roi_c.width * roi_c.height; // Get the area of current element (detected face) 

    roi_b.x = faces[ib].x; 
    roi_b.y = faces[ib].y; 
    roi_b.width = (faces[ib].width); 
    roi_b.height = (faces[ib].height); 

    ab = roi_b.width * roi_b.height; // Get the area of biggest element, at beginning it is same as "current" element 

    if (ac > ab) 
    { 
     ib = ic; 
     roi_b.x = faces[ib].x; 
     roi_b.y = faces[ib].y; 
     roi_b.width = (faces[ib].width); 
     roi_b.height = (faces[ib].height); 
    } 

    crop = frame(roi_b); 
    resize(crop, res, Size(128, 128), 0, 0, INTER_LINEAR); // This will be needed later while saving images 
    cvtColor(crop, gray, CV_BGR2GRAY); // Convert cropped image to Grayscale 

    // Form a filename 
    filename = ""; 
    stringstream ssfn; 
    ssfn << filenumber << ".png"; 
    filename = ssfn.str(); 
    filenumber++; 

    imwrite(filename, gray); 
    printf("filename"); 
    Point pt1(faces[ic].x, faces[ic].y); // Display detected faces on main window - live stream from camera 
    Point pt2((faces[ic].x + faces[ic].height), (faces[ic].y + faces[ic].width)); 
    rectangle(frame, pt1, pt2, Scalar(0, 255, 0), 2, 8, 0); 
} 

// Show image 
/*sstm << "Crop area size: " << roi_b.width << "x" << roi_b.height << " Filename: " << filename; 
text = sstm.str(); 

putText(frame, text, cvPoint(30, 30), FONT_HERSHEY_COMPLEX_SMALL, 0.8, cvScalar(0, 0, 255), 1, CV_AA); 
imshow("original", frame); 

if (!crop.empty()) 
{ 
    imshow("detected", crop); 
} 
else 
    destroyWindow("detected");*/ 

}

+1

我建議你看看圖像,找到臉並計數。 – zmbq

+0

請首先學習如何從openCV文件加載圖像以及如何在窗口中顯示它們。 – Micka

+1

'int numberOfFacesInThisImage = faces.size()'after detectMultiscale – Micka

回答

0

我不得不做類似的事情和OpenCV的網站上使用的CascadeClassifierexample

粗糙的步驟如下是:

  1. 負載要處理所有圖像。
  2. 對於每個圖像,應用CascadeClassifier(如示例中所示),則需要傳遞std::vector<cv::Rect>作爲參數。檢測後,這個向量將包含所有檢測到的對象的位置(在你的情況下,面)。
  3. 對於每幅圖像,返回矢量的大小以知道檢測到的面的數量。

說實話,我掛的例子是你可能會對自己的發現沒有太多的精力。

+0

謝謝,但問題是一個初學者,雖然這個例子就像我已經發現的所有例子都使用視頻流。 – laeemra

+0

要從文件加載圖像,請查看[此鏈接](http://docs.opencv.org/doc/tutorials/introduction/display_image/display_image.html)。你必須使用'cv :: imread()'函數。它將返回一個表示圖像的'cv :: Mat'對象,並可以在我在答案中提到的示例中使用。 –

1

修改你發佈的代碼示例只返回圖像中檢測到的面部數量...

// Function to count the detected faces in your image 
void countFacesInImage(Mat frame) 
{ 
    std::vector<Rect> faces; 
    Mat frame_gray; 

    cvtColor(frame, frame_gray, COLOR_BGR2GRAY); 
    equalizeHist(frame_gray, frame_gray); 

    // Detect faces 
    face_cascade.detectMultiScale(frame_gray, faces, 1.1, 2, 0 |  CASCADE_SCALE_IMAGE, Size(30, 30)); 

    return faces.size(); 
} 
如果你想獲得其中的臉被檢測出並沒有可以添加的印象

這個代碼在返回之前:

cv::Mat tmpImage = frame.clone(); 
for(unsigned int i=0; i<faces.size(); ++i) 
{ 
    cv::rectangle(tmpImage, faces[i], cv::Scalar(0,255,0), 2); 
} 
cv::imshow("faces", tmpImage); 
cv::waitKey(0); 

在每個圖像之後,您必須按下具有活動窗口「faces」的按鍵。您可以更改爲cv::waitKey(n)以等待n毫秒,而不需要按鍵。

+0

謝謝...它真的有幫助,但我必須設置興趣區?因爲我的圖像有一些錯誤的數字 – laeemra

+0

如果你想在整幅圖像中檢測到人臉,你不必使用任何投資回報(如果你需要投資回報率,你只需將裁剪後的投資回報率圖像傳遞給函數)。但哈斯級聯面部檢測並不準確,所以你可能因爲檢測器的準確性而得到錯誤的值。我聽說'dlib'庫的人臉檢測器更準確,但還沒有測試。 http://dlib.net/ – Micka

+0

如果您想要了解哪些面部被檢測到,哪些面部不適,您可以嘗試添加新的代碼片段。 – Micka