OpenCV: OpenCV人臉檢測框可信度排序
阿新 • • 發佈:2019-01-27
使用OpenCV進行人臉識別時,使用
casecade.detectMultiScale函式,可輸出每個檢測框的置信度
程式碼段:
函式原型:const int numReserve = 4; std::vector< int > rejLevel; std::vector<double> levelW; cascade.detectMultiScale( smallImg, eyes, rejLevel, levelW, 1.1, 3, 0, cv::Size(), cv::Size(), true); cout << "eyes size=:" << eyes.size() << endl; // 重新排序 std::vector<std::pair<float, int> > eyeConfi; for (int i = 0; i < (int)(eyes.size()); i++){ eyeConfi.push_back(std::make_pair(levelW[i], i)); } std::qsort(&eyeConfi[0], eyeConfi.size(), sizeof(eyeConfi[0]), cmpMapWishchin); //重新獲取,只取前四個 for (int i = 0; i < (int)(eyes.size()) && i<numReserve ; i++) { cv::Rect eyeSin = eyes[eyeConfi[i].second]; eyesFinal.push_back(eyeSin) ; }
CV_WRAP virtual void detectMultiScale( const Mat& image, CV_OUT vector<Rect>& objects, vector<int>& rejectLevels, vector<double>& levelWeights, double scaleFactor=1.1, int minNeighbors=3, int flags=0, Size minSize=Size(), Size maxSize=Size(), bool outputRejectLevels=false );
cmp函式:
int cmpMapWishchin(const void *p1, const void *p2) { int v = 1; std::pair<float, int > *pp1, *pp2; pp1 = (std::pair<float, int > *) p1; pp2 = (std::pair<float, int > *) p2; //最大值排序 if (pp1->first - pp2->first < 0){ v = 1; } else{ v = -1; } return (v); }
函式的原理是這樣的(個人理解,有錯誤請指教):
首先一個level一個level地測試樣本,然後每一個level給一個對應的得分,也就是levelWeight,如果這個weight低於或者高於對應level的threshold,則被拋棄。
堅持到最後一個level並且在最後一個level仍然滿足threshold的框就是正確的臉(正樣本)。
所以,人臉的分應該是這樣:level越大,分數越高,在相同的level,levelWeight越大分數越高。
但是實際上真正的人臉都是能堅持到level20(最後一個level)的,所以只比對最後一個level的所有大於1的框的levelWeight進行比對就可以知道臉的得分啦~
試驗結果: