OpenCV之影象特徵提取與檢測(十) HOG特徵檢測
阿新 • • 發佈:2019-02-04
用於人像的識別,動物識別。需要提前錄入訓練資料,才能進行對比識別,OpenCV中已經錄入了行人的訓練資料
HOG(Histogram of Oriented Gradient)特徵描述子提取:
- 灰度影象轉換—gray = R*0.3 + 0.59*G + 0.11*B
- 梯度計算—sobel運算元計算梯度,畫素點的兩個特徵:方向(角度)與梯度
- 分網格的梯度方向直方圖
- 塊描述子—方塊的:R-HOG 圓形的:C-HOG
- 塊描述子歸一化 —至此得到了 HOG特徵的資料了
特徵資料與檢測視窗
最終獲得HOG描述運算元(特徵資料) 需要正向訓練200個左右的特徵樣本 反向訓練600~800個左右的特徵樣本 初步測試、開窗檢測 舉例: 對於64x128的畫素塊,可以分為8x16個Cell分為7x15個塊(R-HOG) 總計的直方圖向量數為: 7x15x2x2x9 = 3780個向量陣列
匹配方法
cv::HOGDescriptor HOGDescriptor( // HOG特徵描述子提取 Size _winSize, // 視窗大小,對應上面舉例的 64x128 Size _blockSize, // 2x2個_cellSize,也就是 16x16 Size _blockStride, // 每次移動步長,也就是 _cellSize的尺寸 8x8 Size _cellSize, // 8x8 int _nbins, // 對梯度方向直方圖中的bins 9 int _derivAperture=1, // 求梯度的引數 double _winSigma=-1, int _histogramNormType=HOGDescriptor::L2Hys, // 求直方圖的引數 double _L2HysThreshold=0.2, // 歸一化閾值引數 bool _gammaCorrection=false, // 對於灰度的輸入影象是否要做伽馬校正 int _nlevels=HOGDescriptor::DEFAULT_NLEVELS, bool _signedGradient=false
)
程式碼
#include "../common/common.hpp" void main(int argc, char** argv) { Mat src = imread(getCVImagesPath("images/hogman.png")); imshow("src-13", src); // HOG特徵描述子 Mat dst, dst_gray; resize(src, dst, Size(64, 128)); // 將原始影象變成 64x128 尺寸 imshow("resize2-13", dst); cvtColor(dst, dst_gray, COLOR_BGR2GRAY); HOGDescriptor detector(Size(64, 128), Size(16, 16), Size(8, 8), Size(8, 8), 9); // HOG特徵描述子提取類 vector<float> descriptors; // 儲存舉例中的計算出來的3780個向量陣列 vector<Point> locations; // 作用? detector.compute(dst_gray, descriptors, Size(0, 0), Size(0, 0), locations); // 計算HOG特徵描述子 // descriptors.size=3780, locations.size=0 cout << "descriptors.size=" << descriptors.size() << ", locations.size=" << locations.size() << endl; // HOG+SVM 實現行人檢測 Mat walkers = imread(getCVImagesPath("images/HOGV.png")); imshow("walkers", walkers); HOGDescriptor hog = HOGDescriptor(); hog.setSVMDetector(hog.getDefaultPeopleDetector()); // opencv自帶的封裝好了行人資料的Detector vector<Rect> foundLocations; // 儲存檢測到的行人的 Rect hog.detectMultiScale(walkers, foundLocations, 0, Size(8, 8), Size(32, 32), 1.05, 2); // 在多個尺寸上尋找,detect 同一尺度 cout << "foundLocations.size=" << foundLocations.size() << endl; // foundLocations.size=3 Mat result = walkers.clone(); for (size_t t = 0; t < foundLocations.size(); t++) { rectangle(result, foundLocations[t], Scalar(0, 0, 255), 2, 8, 0); // 繪製行人的方框 } imshow("HOG SVM Detector", result); waitKey(0); }