其定義在 object.hpp中找到的:
- struct CV_EXPORTS_W HOGDescriptor
- {
- public:
- enum { L2Hys=0 };
- enum { DEFAULT_NLEVELS=64 };
- CV_WRAP HOGDescriptor() : winSize(64,128), blockSize(16,16), blockStride(8,8),
- cellSize(8,8), nbins(9), derivAperture(1), winSigma(-1),
- histogramNormType(HOGDescriptor::L2Hys), L2HysThreshold(0.2), gammaCorrection(true),
- nlevels(HOGDescriptor::DEFAULT_NLEVELS)
- {}
- CV_WRAP HOGDescriptor(Size _winSize, Size _blockSize, Size _blockStride,
- Size _cellSize, int _nbins, int _derivAperture=1, double _winSigma=-1,
- int _histogramNormType=HOGDescriptor::L2Hys,
- double _L2HysThreshold=0.2, bool _gammaCorrection=false,
- int _nlevels=HOGDescriptor::DEFAULT_NLEVELS)
- : winSize(_winSize), blockSize(_blockSize), blockStride(_blockStride), cellSize(_cellSize),
- nbins(_nbins), derivAperture(_derivAperture), winSigma(_winSigma),
- histogramNormType(_histogramNormType), L2HysThreshold(_L2HysThreshold),
- gammaCorrection(_gammaCorrection), nlevels(_nlevels)
- {}
- CV_WRAP HOGDescriptor(const String& filename)
- {
- load(filename);
- }
- HOGDescriptor(const HOGDescriptor& d)
- {
- d.copyTo(*this);
- }
- virtual ~HOGDescriptor() {}
- CV_WRAP size_t getDescriptorSize() const;
- CV_WRAP bool checkDetectorSize() const;
- CV_WRAP double getWinSigma() const;
- CV_WRAP virtual void setSVMDetector(InputArray _svmdetector);
- virtual bool read(FileNode& fn);
- virtual void write(FileStorage& fs, const String& objname) const;
- CV_WRAP virtual bool load(const String& filename, const String& objname=String());
- CV_WRAP virtual void save(const String& filename, const String& objname=String()) const;
- virtual void copyTo(HOGDescriptor& c) const;
- CV_WRAP virtual void compute(const Mat& img,
- CV_OUT vector<float>& descriptors,
- Size winStride=Size(), Size padding=Size(),
- const vector<Point>& locations=vector<Point>()) const;
- //with found weights output
- CV_WRAP virtual void detect(const Mat& img, CV_OUT vector<Point>& foundLocations,
- CV_OUT vector<double>& weights,
- double hitThreshold=0, Size winStride=Size(),
- Size padding=Size(),
- const vector<Point>& searchLocations=vector<Point>()) const;
- //without found weights output
- virtual void detect(const Mat& img, CV_OUT vector<Point>& foundLocations,
- double hitThreshold=0, Size winStride=Size(),
- Size padding=Size(),
- const vector<Point>& searchLocations=vector<Point>()) const;
- //with result weights output
- CV_WRAP virtual void detectMultiScale(const Mat& img, CV_OUT vector<Rect>& foundLocations,
- CV_OUT vector<double>& foundWeights, double hitThreshold=0,
- Size winStride=Size(), Size padding=Size(), double scale=1.05,
- double finalThreshold=2.0,bool useMeanshiftGrouping = false) const;
- //without found weights output
- virtual void detectMultiScale(const Mat& img, CV_OUT vector<Rect>& foundLocations,
- double hitThreshold=0, Size winStride=Size(),
- Size padding=Size(), double scale=1.05,
- double finalThreshold=2.0, bool useMeanshiftGrouping = false) const;
- CV_WRAP virtual void computeGradient(const Mat& img, CV_OUT Mat& grad, CV_OUT Mat& angleOfs,
- Size paddingTL=Size(), Size paddingBR=Size()) const;
- CV_WRAP static vector<float> getDefaultPeopleDetector();
- CV_WRAP static vector<float> getDaimlerPeopleDetector();
- CV_PROP Size winSize;
- CV_PROP Size blockSize;
- CV_PROP Size blockStride;
- CV_PROP Size cellSize;
- CV_PROP int nbins;
- CV_PROP int derivAperture;
- CV_PROP double winSigma;
- CV_PROP int histogramNormType;
- CV_PROP double L2HysThreshold;
- CV_PROP bool gammaCorrection;
- CV_PROP vector<float> svmDetector;
- CV_PROP int nlevels;
- // evaluate specified ROI and return confidence value for each location
- void detectROI(const cv::Mat& img, const vector<cv::Point> &locations,
- CV_OUT std::vector<cv::Point>& foundLocations, CV_OUT std::vector<double>& confidences,
- double hitThreshold = 0, cv::Size winStride = Size(),
- cv::Size padding = Size()) const;
- // evaluate specified ROI and return confidence value for each location in multiple scales
- void detectMultiScaleROI(const cv::Mat& img,
- CV_OUT std::vector<cv::Rect>& foundLocations,
- std::vector<DetectionROI>& locations,
- double hitThreshold = 0,
- int groupThreshold = 0) const;
- // read/parse Dalal's alt model file
- void readALTModel(std::string modelfile);
- };
默認構造函數的幾個參數:
- winSize(64,128), blockSize(16,16), blockStride(8,8),
- cellSize(8,8), nbins(9), derivAperture(1), winSigma(-1),
- histogramNormType(HOGDescriptor::L2Hys), L2HysThreshold(0.2), gammaCorrection(true),
- nlevels(HOGDescriptor::DEFAULT_NLEVELS)
winSize : 窗口的大小
blockSize :塊的大小
cellSize: 胞元的大小
nbins: 方向bin的個數 nBins表示在一個胞元(cell)中統計梯度的方向數目,例如nBins=9時,在一個胞元內統計9個方向的梯度直方圖,每個方向為360/9=40度。
更詳細請移步: http://blog.csdn.NET/raocong2010/article/details/6239431
=++++++++++++++++++++++提取 HOG 特征+++++++++++++++++++++++++=
//樣本矩陣,nImgNum:橫坐標是樣本數量。 列數是該 樣本對應的 特征維數。ex: 樣本是學生,其樣本特征可以由 身高,體重,年齡 組成,那么 第二個參數就是 3 啦。
CvMat *data_mat = cvCreateMat( nImgNum, 1764, CV_32FC1 );
//類型矩陣,存儲每個樣本的類型標志 , 一維,只需要存儲該樣本屬於哪一類即可(只有兩類)
CvMat * res_mat = cvCreateMat( nImgNum, 1, CV_32FC1 );
HOGDescriptor *hog=new HOGDescriptor(cvSize(64,64),cvSize(16,16),cvSize(8,8),cvSize(8,8),9);
// 計算hog特征
// trainImg是讀入的需要計算特征的圖像,IplImage* trainImg=cvCreateImage(cvSize(64,64),8,3);
//descriptors 是結果數組 vector<float> descriptors; HOG特征的維數就是 = descriptors.size 啦,上例中,就是 那個3 啦。
hog->compute(trainImg, descriptors,Size(1,1), Size(0,0));
//計算完成后,把hog特征存儲到 上面聲明的那個 樣本 矩陣中
// i 是當前處理的第 i 張 圖片, n 從 0 開始 ++ ,從第 0 列 開始存儲。 *iter 是 (vector<float>::iterator iter=descriptors.begin();iter!=descriptors.end();iter++)
cvmSet(data_mat, i, n,*iter);
// 訓練讀入的圖片是有 標簽 的( 知道已知屬於哪一類), 將標簽存入 標簽 矩陣 。i 是當前處理的 圖片 的 編號。 img_catg[i] 是 讀入 的已知的 數據。
cvmSet( res_mat, i, 0, img_catg[i] );
++++++++++++++++++++++++++++++++++開始訓練+++++++++++++++++++++++++++
首先要/新建一個SVM
CvSVM svm = CvSVM();
// 開始訓練~
svm.train( data_mat, res_mat, NULL, NULL, param ); //data_mat 是 上面提取 到的 HOG特征,存儲 m 個樣本的 n 個特征, res_mat 是標簽矩陣,m個樣本屬於哪一類,已 // 知的。 param 的定義如下:
CvSVMParams param = CvSVMParams( CvSVM::C_SVC, CvSVM::RBF, 10.0, 0.09, 1.0, 10.0, 0.5, 1.0, NULL, criteria );
CvTermCriteria criteria = cvTermCriteria( CV_TERMCRIT_EPS, 1000, FLT_EPSILON );
// 將訓練結果保存在 xml文件中
svm.save( "SVM_DATA.xml" );
此階段生成文件:
SVM_DATA.xml
訓練完成之后,就開始 對 你所需要 的 數據 進行 預測。 這里預測 當前 圖片 屬於 那一類別。
++++++++++++++++++++++++++++++++++檢測樣本+++++++++++++++++++++++++++
讀入當前要預測的圖片 testImg
將testImg 縮放 至 與 訓練圖片 一樣大小 ,直接存放到 trainImg中
計算讀入的圖片的Hog特征,
hog->compute(trainImg, descriptors,Size(1,1), Size(0,0)); //調用計算函數開始計算
仍用 vector<float> descriptors; 存放結果
創建一個 一行 n 列 的向量。 n 是 特征的個數 。 就是上面的 3 啊, descriptors.size() 啊。 用來存放 當前要預測的圖片的 特征
CvMat* SVMtrainMat=cvCreateMat(1,descriptors.size(),CV_32FC1);
// 開始預測
int ret = svm.predict(SVMtrainMat);
ret 返回的是 當前 預測 的 圖片 的 類別。 就是 一開始 讀到 標簽 矩陣 中的 數據。 一般 用 0 or 1 來標示 兩大類別。
可將結果文件保存在:
SVM_PREDICT.txt
+++++++++++++++++=OpenCV HOG特征向量個數計算方法+++++++++++++++++++++++
下面參照 網上 方法 說下 怎么計算 的 每個向量 的 特征 維數, 就是一開始就聲明 的
樣本矩陣 CvMat *data_mat = cvCreateMat( nImgNum, 1764, CV_32FC1 );
中這個 1764 是如何計算出來的。
1. 先確定 你 要訓練 以及 檢測 的圖片 的 大小 IplImage* trainImg=cvCreateImage(cvSize(64,64),8,3);
ok 這里是 64 x 64
2. 確定 HOGDescriptor *hog=new HOGDescriptor(cvSize(64,64),cvSize(16,16),cvSize(8,8),cvSize(8,8),9);
第一個 窗口 大小 設置 為 上面的圖片大小 64 x 64 。
第二個 塊大小 是 16 x 16 的話 [ 額 這個腫么確定?與前面的 窗口大小有關系 么? 這是opencv中默認的大小]
第三個 塊block的步進 stride 8 x 8
第四個是 胞元cell大小 8 x 8
第五個是 cell的直方圖的 bin = 9 [ 不懂 +_+]
每個 cell 有 9 個向量
每個block 有 (16 / 8 ) * (16 / 8) = 2 * 2 = 4 個 cell, 那么現在就有 4 * 9 = 36 個向量啦
每個 窗口 有多少個 block 呢?
利用公式 (window_size - block_size)/block_stride + 1 對兩個方向進行計算:
( 64 - 16) / 8 + 1 = 7
兩個方向 7 * 7 = 49
so 共有 49* 36 = 1764