OpenCV HOG+SVM行人檢測:從訓練到檢測
以現在使用的OpenCV 2.4.10為例,行人檢測的Demo在“D:\opencv\sources\samples\cpp\peopledetect.cpp”下,原始碼如下所示:
#include "opencv2/imgproc/imgproc.hpp" #include "opencv2/objdetect/objdetect.hpp" #include "opencv2/highgui/highgui.hpp" #include <stdio.h> #include <string.h> #include <ctype.h> using namespace cv; using namespace std; // static void help() // { // printf( // "\nDemonstrate the use of the HoG descriptor using\n" // " HOGDescriptor::hog.setSVMDetector(HOGDescriptor::getDefaultPeopleDetector());\n" // "Usage:\n" // "./peopledetect (<image_filename> | <image_list>.txt)\n\n"); // } int main(int argc, char** argv) { Mat img; FILE* f = 0; char _filename[1024]; if( argc == 1 ) { printf("Usage: peopledetect (<image_filename> | <image_list>.txt)\n"); return 0; } img = imread(argv[1]); if( img.data ) { strcpy(_filename, argv[1]); } else { f = fopen(argv[1], "rt"); if(!f) { fprintf( stderr, "ERROR: the specified file could not be loaded\n"); return -1; } } HOGDescriptor hog; hog.setSVMDetector(HOGDescriptor::getDefaultPeopleDetector()); namedWindow("people detector", 1); for(;;) { char* filename = _filename; if(f) { if(!fgets(filename, (int)sizeof(_filename)-2, f)) break; //while(*filename && isspace(*filename)) // ++filename; if(filename[0] == '#') continue; int l = (int)strlen(filename); while(l > 0 && isspace(filename[l-1])) --l; filename[l] = '\0'; img = imread(filename); } printf("%s:\n", filename); if(!img.data) continue; fflush(stdout); vector<Rect> found, found_filtered; double t = (double)getTickCount(); // run the detector with default parameters. to get a higher hit-rate // (and more false alarms, respectively), decrease the hitThreshold and // groupThreshold (set groupThreshold to 0 to turn off the grouping completely). hog.detectMultiScale(img, found, 0, Size(8,8), Size(32,32), 1.05, 2); t = (double)getTickCount() - t; printf("tdetection time = %gms\n", t*1000./cv::getTickFrequency()); size_t i, j; for( i = 0; i < found.size(); i++ ) { Rect r = found[i]; for( j = 0; j < found.size(); j++ ) if( j != i && (r & found[j]) == r) break; if( j == found.size() ) found_filtered.push_back(r); } for( i = 0; i < found_filtered.size(); i++ ) { Rect r = found_filtered[i]; // the HOG detector returns slightly larger rectangles than the real objects. // so we slightly shrink the rectangles to get a nicer output. 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(img, r.tl(), r.br(), cv::Scalar(0,255,0), 3); } imshow("people detector", img); int c = waitKey(0) & 255; if( c == 'q' || c == 'Q' || !f) break; } if(f) fclose(f); return 0; }
在該Demo裡,沒有類似人類檢測時的分類器(模型)的載入過程,而是用下面的語句載入預設模型:
hog.setSVMDetector(HOGDescriptor::getDefaultPeopleDetector());
該函式的原始碼位於 D:\opencv\sources\modules\objdetect\src\hog.cpp 檔案中第 1081 行開始,擷取片段如下所示:
vector<float> HOGDescriptor::getDefaultPeopleDetector() { static const float detector[] = { 0.05359386f, -0.14721455f, -0.05532170f, 0.05077307f, 0.11547081f, -0.04268804f, 0.04635834f, -0.05468199f, 0.08232084f, 0.10424068f, -0.02294518f, 0.01108519f, 0.01378693f, 0.11193510f, 0.01268418f, 0.08528346f, -0.06309239f, 0.13054633f, 0.08100729f, -0.05209739f, -0.04315529f, 0.09341384f, 0.11035026f, -0.07596218f, -0.05517511f, -0.04465296f, 0.02947334f, 0.04555536f, -3.55954492e-003f, 0.07818956f, 0.07730991f, 0.07890715f, 0.06222893f, 0.09001380f, -0.03574381f, 0.03414327f, 0.05677258f, -0.04773581f, 0.03746637f, -0.03521175f, 0.06955440f, -0.03849038f, 0.01052293f, 0.01736112f, 0.10867710f, 0.08748853f, 3.29739624e-003f, 0.10907028f, 0.07913758f, 0.10393070f, 0.02091867f, 0.11594022f, 0.13182420f,
從上可知,行人檢測所用到的模型資料被作為常量寫在原始碼裡面,有如下問題:
1)這些模型資料是如何得來的?
2)如果使用我自己的樣本進行trainning,使用得到的model去detect該如何操作?
首先,從OpenCV所使用到的行人檢測演算法說起,OpenCV行人檢測所用到的演算法源自Navneet Dalal和Bil Triggs 在2005年 CVPR 上的文章Histograms of Oriented Gradients for Human Detection 作者所在的研究機構
(INRIA:French National Institute for Research in Computer Science and Control,法國國家計算機技術和控制研究所)釋出了這套演算法的原始碼
那麼,OpenCV是否原封不動的使用了這套演算法呢?為了求證該問題,筆者比較了兩者的模型資料,下載OLTbinaries.zip 找到 /HOG/model_4BiSVMLight.alt 檔案(二進位制形式的資料),用程式碼將其中資料儲存為文字格式(這個要根據上面的原始碼learncode),其內容如下:
0.05359386f, -0.14721455f, -0.05532170f, 0.05077307f,
0.11547081f, -0.04268804f, 0.04635834f, -0.05468199f, 0.08232084f,
0.10424068f, -0.02294518f, 0.01108519f, 0.01378693f, 0.11193510f,
0.01268418f, 0.08528346f, -0.06309239f, 0.13054633f, 0.08100729f,
-0.05209739f, -0.04315529f, 0.09341384f, 0.11035026f, -0.07596218f,
-0.05517511f, -0.04465296f, 0.02947334f, 0.04555536f,
-3.55954492e-003f, 0.07818956f, 0.07730991f, 0.07890715f, 0.06222893f,
0.09001380f, -0.03574381f, 0.03414327f, 0.05677258f, -0.04773581f,
0.03746637f, -0.03521175f, 0.06955440f, -0.03849038f, 0.01052293f,
0.01736112f, 0.10867710f, 0.08748853f, 3.29739624e-003f, 0.10907028f,
0.07913758f, 0.10393070f, 0.02091867f, 0.11594022f, 0.13182420f,
由此可見,兩者的資料一模一樣。那麼你使用OLT去trainning你的樣本,把得到的model替換getDefaultPeopleDetector() 中的資料,就可以進行你自己的目標檢測了!---------------------------------------------------------------------------------------------------------
訓練樣本
為了驗證這一想法的正確性和可行性,筆者進行了實驗,使用的環境為 Ubuntu10.4 g++ 4.4.5:
具體實現步驟如下:
3)在OLTbinaries/ 下建立兩個資料夾 test, train,將INRIAperson/Test/neg拷貝到 test/ 下,INRIAperson/Train/neg拷貝到 train/ 下;將INRIAperson/test_64x128_H96拷貝到 test/ 下,重新命名為 pos, INRIAperson/train_64x128_H96 拷貝到 train/ 下,重新命名為 pos;
4)將 test/neg, test/pos 各自資料夾中的所有圖片檔名分別輸出到 neg.list, pos.list,並放置在 test/ 下,同樣的操作在 train/。
<pre class="brush: shell; gutter: true">[email protected]:~/Projects/opencv/OLTbinaries/test$ ls ./neg > neg.list
[email protected]:~/Projects/opencv/OLTbinaries/test$ ls ./pos > pos.list</pre>
5)到這裡,樣本資料便準備好了,只要修改 OLTbinaries/runall.sh 相關引數,然後執行這些指令碼,一個小時左右的時間,便會在 OLTbinaries/HOG 下產生一個 model_4BiSVMLight.alt檔案,模型資料便儲存在這裡,到這裡,你便成功 trainning 了一個 model。
注意事項:
- runall.sh 中第 5 行,按你的正負樣本數目修改:
HardOption=" --poscases 2416 --negcases 12180 "
- runall.sh 中第 21 行,樣本資料夾及輸出資料夾所在位置:
OutDir=HOG
OutFile=$OutDir/record
CMDLINE=$OutDir/record
- trainning 過程中會產生 2 個 G 左右的臨時檔案在 OutDir(=./HOG)中,結束時刪除,只保留model_4BiSVMLight.alt。
- 整個 trainning 過程分為4步, 有4條螢幕輸出資訊:
First
iteration complete
Hard
examples created
Doing
second learning
Second
iteration complete
- 如果使用的是自己的樣本,注意修改其他引數(待糾),如正樣本的大小:
WIDTH=64; export WIDTH
HEIGHT=128; export HEIGHT
檢測過程待補
相關推薦
OpenCV HOG+SVM行人檢測:從訓練到檢測
以現在使用的OpenCV 2.4.10為例,行人檢測的Demo在“D:\opencv\sources\samples\cpp\peopledetect.cpp”下,原始碼如下所示: #include "opencv2/imgproc/imgproc.hpp" #incl
OPENCV HOG特徵+SVM分類器行人識別(從訓練到識別)
想要訓練分類器,首先要有樣本,正樣本和負樣本,在這裡就是有人的樣本和沒有人的樣本,我的樣本來源於”INRIA Person Dataset”這個網站,連結為點選開啟連結,在下邊有個藍色here(970M),點選下載即可,也可以去我的網盤下載,地址點選開啟
opencv +Hog + SVM 車輛檢測
最近嘗試了一下用opencv做了一下車輛檢測 其中hog特徵使用opencv自帶函式庫進行提取描述如下: HOGDescriptor *hog = new HOGDescriptor(Size(64, 64), Size(16, 16), Size(8, 8), Size(8, 8)
HOG+SVM行人檢測的兩種方法
關於HOG+SVM,CSDN上有一些非常好的文章,這裡給出我覺得寫的比較好的幾篇,僅供大家參考 以上就是個人覺得寫的比較好的部落格,基本上將上面的部落格看懂了,HOG也比較理解了,如果還想輸入瞭解HOG,建議直接看OpenCV HOG的原始碼 下面,就說
C++ Opencv Hog+svm 二分類
// opencv3 #include <stdio.h> #include <iostream> #include <fstream> #include <opencv2/opencv.hpp> #include <string>
C++ Opencv——Hog+SVM
思路: // HOG描述子向量 std::vector<float> descriptors; cv::HOGDescriptor hog(cv::Size(48, 48), cv::Size(16, 16), cv::Size(8, 8), cv::Size(8, 8)
SVM全系列:從原理到python實現(一):SVM原理
前言 本文開始主要介紹一下SVM的分類原理以及SVM的數學匯出和SVM在Python上的實現。借鑑了許多文章,會在後面一一指出,如果有什麼不對的希望能指正。 一、 SVM簡介 首先看到SVM是在斯坦福的機器學習課程上,SVM是作為分類器在logisticregr
基於深度學習的目標檢測技術演進:從目標檢測到人臉檢測
本篇部落格主要轉載兩篇寫得好的分別介紹基於深度學習的目標檢測和人臉檢測的文章,最近在調研基於深度學習的人臉檢測相關的文章,在網上查相關資料時,有幸看到。文末附帶基於深度學習的目標檢測和人臉檢測相關經典文獻及下載地址。 object detection我
OpenCV成長之路(9):特徵點檢測與影象匹配
特徵點檢測與影象匹配 稱興趣點、關鍵點,它是在影象中突出且具有代表意義的一些點,通過這些點我們可以用來識別影象、進行影象配準、進行3D重建等。本文主要介紹OpenCV中幾種定位與表示關鍵點的函式。 一、Harris角點 角點是影象中最基本的一種關鍵點,它是由影象中一些幾何
走近人臉檢測:從VJ到深度學習(上)
http://mt.sohu.com/20160413/n444091833.shtml 作者:鄔書哲 中科院計算所智慧資訊處理重點實驗室VIPL課題組博士生 研究方向:目標檢測,尤其關注基於深度學習的目標檢測方法。 本文分上下兩篇,上篇主要介紹人臉檢測的基本流程,以及傳統的VJ人臉檢測器及
車牌識別技術詳解五--採用LBP+HOG SVM做目標分類,車牌檢測,字元檢測等
在樣本數量比較少的情況下,可以採用HOG、SVM對樣本進行初步的篩選出,正負樣本,本文接著上一節二值化出來部分樣本後,用pictureRelate做初步篩選出正負樣本各50
表面缺陷檢測:機器視覺檢測技術
導讀:傳統的工業生產製造,由於科學技術的限制仍然主要採用人工檢測的方法去檢測產品表面的缺陷,這種方法由於人工的限制和技術的落後,不僅檢測產品的速度慢、效率低下,而且在檢測的過程中容易出錯,從而導致了檢測結果的不精確。 當今社會,隨著計算機技術,人工智慧等科學技術的出
opencv︱opencv中實現行人檢測:HOG+SVM(二)
零、行人檢測綜述 行人檢測,就是將一張圖片中的行人檢測出來,並輸出bounding box級別的結果。而如果將各個行人之間的軌跡關聯起來,就變成了行人跟蹤。而行人檢索則是把一段視訊中的某個感興趣的人檢索出來。 行人檢測領域的工作
Opencv實現行人檢測(HOG + SVM)
1. 理論基礎 使用OpenCv進行行人檢測的主要思想: HOG + SVM HOG: 方向梯度直方圖(Histogram of Oriented Gradient, HOG)特徵是一種在計算機視覺和影象處理中用來進行物體檢測的特徵描述子。HOG特徵通過計
python通過HOG+SVM實現行人檢測思路
一、思路 1、選取視窗寬高為 64*128 ,block大小為 16*16畫素,block步長為8畫素,cell為8*8畫素,每個cell分9個bin,其他引數都預設 這樣的話,一個block有4個cell,一個cell有9維,那一
利用HOG+SVM實現行人檢測
利用HOG+SVM實現行人檢測 很久以前做的行人檢測,現在稍加溫習,上傳記錄一下。 首先解析視訊,提取視訊的每一幀形成圖片存到磁碟。程式碼如下 import os import cv2 videos_src_path = 'D:\\test1' videos_save_path = 'D:\\tes
hog+svm 實現行人檢測(C++ opencv3.4)
最近想學下傳統機器學習方法來實現目標檢測,從頭到尾下來記錄下自己的程式碼過程行人檢測加粗樣式 資料集準備:INRIA行人檢測資料集百度雲下載,http://pan.baidu.com/s/1eSdlw7g 下載完之後我們解壓可以看到資料集檔案分佈 INRIADA
HOG+SVM實現行人檢測
一、概述 行人檢測過去流行採用的方法是DPM方法,其主要採用hog特徵+SVM分類實現行人檢測; 其中梯度方向直方圖( Histogram of Oriented Gradients,HOG)的概念是 Dalal和Triggs在2005年提出,並將其用於行人檢測
OpenCV的HOG+SVM訓練程式注意事項
關於訓練程式我封裝了一份,大家可以參考一下 http://download.csdn.net/detail/xidianzhimeng/8270413 樣本的配置與OpenCV訓練Adaboost的類似,相信訓練過Adaboost的同學能很快入手的。 用Ope
行人檢測(haar+adaboost 與 hog+SVM)
最近在做行人檢測,而最流行,也是最老的兩種方法就是haar+adaboost 與 hog+SVM。兩種我都嘗試了,效果並不如想象的好,所以要想有更好的效果,一是要有預處理,二是要有更大量的正負樣本。 下面現總結一下自己應用的 haar+Adaboost 進行的行人檢測