OpenCv-C++-HOG特徵檢測演算法
HOG主要是用來做行人檢測的,HOG方法是基於對稠密網格中歸一化的區域性方向梯度直方圖的計算。此方法的基本觀點是:區域性目標的外表和形狀可以被區域性梯度或邊緣方向的分佈很好的描述,即使我們不知道對應的梯度和邊緣的位置。在實際操作中,將影象分為小的元胞(cells),在每個元胞內累加計算出一維的梯度方向(或邊緣方向)直方圖。為了對光照和陰影有更好的不變性,需要對直方圖進行對比度歸一化,這可以通過將元胞組成更大的塊(blocks)並歸一化塊內的所有元胞來實現。歸一化的塊描述符就叫作HOG描述子。將檢測視窗中的所有塊的HOG描述子組合起來就形成了最終的特徵向量,然後使用SVM分類器進行行人檢測。
參考資料:
具體步驟參考這篇文章:https://blog.csdn.net/icvpr/article/details/8454527
在OpenCv中,已經有訓練好的相關API可以使用:
HOGDescriptor hog = HOGDescriptor():
引數使用及說明參考:https://blog.csdn.net/qq_26898461/article/details/46786285
hog.setSVMDetector();
hog.detectMultiScale():
detectMultiscale函式為多尺度多目標檢測。
(1)多尺度:通常搜尋目標的模板尺寸大小是固定的,但是不同圖片大小不同,所以目標物件的大小也是不定的,所以多尺度即不斷縮放圖片大小(縮放到與模板匹配),通過模板滑動窗函式搜尋匹配;同一副圖片可能在不同尺度下都得到匹配值,所以多尺度檢測函式detectMultiscale是多尺度合併的結果。
(2)多目標:通過檢測符合模板匹配物件,可得到多個目標,均輸出到objects向量裡面。
參考:
原始碼:
#include<opencv2/opencv.hpp> #include<iostream> #include<math.h> using namespace cv; using namespace std; Mat src; int main(int argc, char** argv) { src = imread("D:/test/pepole.png"); if(!src.data) { cout << "圖片未找到!" << endl; return -1; } imshow("input title",src); /*resize(src, src, Size(64, 128)); HOGDescriptor detector = HOGDescriptor(Size(64, 128), Size(16, 16), Size(8, 8), Size(8, 8), 9); vector<float>descriptions; vector<Point>points; detector.compute(src, descriptions, Size(0, 0), Size(0, 0), points); cout << "the number of HOG descriptions:" <<descriptions.size()<< endl; */ HOGDescriptor hog = HOGDescriptor(); hog.setSVMDetector(hog.getDefaultPeopleDetector());//opencv中已經有訓練好的行人檢測資料集 Mat resultImg = src.clone(); vector<Rect>foundlocations; hog.detectMultiScale(src, foundlocations, 0, Size(3, 3), Size(32, 32),1.05,2); //根據圖片需要隨時調整Size()大小 for (size_t i = 0; i < foundlocations.size(); i++) { //cout << "foundlocation:" << foundlocations[i] << endl; rectangle(resultImg, foundlocations[i], Scalar(0, 0, 255), 2, 8, 0); } imshow("HOG SVM demo", resultImg); waitKey(0); return 0; }
執行結果: