【機器學習】最簡單易懂的行人檢測功能實現
阿新 • • 發佈:2018-11-07
載入訓練好的行人分類器,實現行人檢測功能。
程式碼中用到的訓練好的行人分類器"pedestrianDetect.xml"下載路徑:https://download.csdn.net/download/lyq_12/10742144
一、效果如下:
1、輸入原圖
2、輸出結果
二、程式碼實現如下:
#include <iostream> #include <fstream> #include <opencv2/core/core.hpp> #include <opencv2/highgui/highgui.hpp> #include <opencv2/imgproc/imgproc.hpp> #include <opencv2/objdetect/objdetect.hpp> #include <opencv2/ml/ml.hpp> using namespace std; using namespace cv; class MySVM : public CvSVM { public: //獲得SVM的決策函式中的alpha陣列 double * get_alpha_vector() { return this->decision_func->alpha; } //獲得SVM的決策函式中的rho引數,即偏移量 float get_rho() { return this->decision_func->rho; } }; int main() { MySVM svm; //SVM分類器 svm.load("pedestrianDetect.xml"); //載入訓練好的行人分類器 int DescriptorDim = svm.get_var_count(); //特徵向量的維數,即HOG描述子的維數 int supportVectorNum = svm.get_support_vector_count(); //支援向量的個數 //cout<<"支援向量個數:"<<supportVectorNum<<endl; Mat alphaMat = Mat::zeros(1, supportVectorNum, CV_32FC1); Mat supportVectorMat = Mat::zeros(supportVectorNum, DescriptorDim, CV_32FC1); Mat resultMat = Mat::zeros(1, DescriptorDim, CV_32FC1); for(int i=0; i<supportVectorNum; i++) { const float * pSVData = svm.get_support_vector(i); for(int j=0; j<DescriptorDim; j++) { supportVectorMat.at<float>(i,j) = pSVData[j]; } } double * pAlphaData = svm.get_alpha_vector(); for(int i=0; i<supportVectorNum; i++) { alphaMat.at<float>(0,i) = pAlphaData[i]; } resultMat = -1 * alphaMat * supportVectorMat; vector<float> myDetector; for(int i=0; i<DescriptorDim; i++) { myDetector.push_back(resultMat.at<float>(0,i)); } myDetector.push_back(svm.get_rho()); //cout<<"檢測子維數:"<<myDetector.size()<<endl; HOGDescriptor myHOG; myHOG.setSVMDetector(myDetector); //設定HOGDescriptor的檢測子 Mat srcImg = imread("..\\srcImg.jpg"); if (srcImg.empty()) { cout<<"Failed to read image."; return -1; } //resize(srcImg, srcImg, Size(288,216)); imshow("srcImg", srcImg); vector<Rect> detectRects, detectRectsAfterNMS; //儲存檢測結果 Mat dstImg = srcImg.clone(); myHOG.detectMultiScale(dstImg, detectRects, 0, Size(8,8), Size(32,32), 1.05, 2); //對輸入圖片進行行人檢測 //對detectRects進行非極大值抑制 for(int i=0; i < detectRects.size(); i++) { Rect r = detectRects[i]; int j=0; for(; j < detectRects.size(); j++) { if(j != i && (r & detectRects[j]) == r) { break; } } if( j == detectRects.size()) { detectRectsAfterNMS.push_back(r); } } //畫出NMS之後的行人檢測結果 for(int i=0; i<detectRectsAfterNMS.size(); i++) { Rect r = detectRectsAfterNMS[i]; r.x += cvRound(r.width*0.1); r.width = cvRound(r.width*0.8); r.y += cvRound(r.height*0.07); r.height = cvRound(r.height*0.8); rectangle(dstImg, r.tl(), r.br(), Scalar(0,255,0), 3); } imshow("dstImg",dstImg); waitKey(0); }
參考資料:https://blog.csdn.net/masibuaa/article/details/16105073?utm_source=tuicool&utm_medium=referral