這部分都是一些介紹,不需要主觀加工,直接收集起來分享之。
1. OpenCV中HOG特徵參數圖解
http://blog.csdn.net/raocong2010/article/details/6239431
最近要做映像特徵提取,可能要用下HOG特徵,所以研究了下OpenCV的HOG描述子。OpenCV中的HOG特徵提取功能使用了HOGDescriptor這個類來進行封裝,其中也有現成的行人檢測的介面。然而,無論是OpenCV官方說明文檔還是各個中英文網站目前都沒有這個類的使用說明,所以在這裡把研究的部分心得分享一下。
首先我們進入HOGDescriptor所在的標頭檔,看看它的建構函式需要哪些參數。
[cpp]
view plaincopyprint?
- 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() : 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) {}
[cpp]
view plaincopyprint?
- 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(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) {}
[cpp]
view plaincopyprint?
- CV_WRAP HOGDescriptor(const String& filename)
- {
- load(filename);
- }
CV_WRAP HOGDescriptor(const String& filename) { load(filename); }
[cpp]
view plaincopyprint?
- HOGDescriptor(const HOGDescriptor& d)
- {
- d.copyTo(*this);
- }
HOGDescriptor(const HOGDescriptor& d) { d.copyTo(*this); }
我們看到HOGDescriptor一共有4個建構函式,前三個有CV_WRAP首碼,表示它們是從DLL裡匯出的函數,即我們在程式當中可以調用的函數;最後一個沒有上述的首碼,所以我們暫時用不到,它其實就是一個拷貝建構函式。
下面我們就把注意力放在前面的建構函式的參數上面吧,這裡有幾個重要的參數要研究下:winSize(64,128), blockSize(16,16), blockStride(8,8), cellSize(8,8), nbins(9)。上面這些都是HOGDescriptor的成員變數,括弧裡的數值是它們的預設值,它們反應了HOG描述子的參數。這裡做了幾個來表示它們的含義。
視窗大小 winSize
塊大小 blockSize
胞元大小 cellSize
梯度方向數 nbins
nBins表示在一個胞元(cell)中統計梯度的方向數目,例如nBins=9時,在一個胞元內統計9個方向的梯度長條圖,每個方向為180/9=20度。
HOG描述子維度
在確定了上述的參數後,我們就可以計算出一個HOG描述子的維度了。OpenCV中的HOG原始碼是按照下面的式子計算出描述子的維度。
[cpp]
view plaincopyprint?
- size_t HOGDescriptor::getDescriptorSize()
const
- {
- CV_Assert(blockSize.width % cellSize.width == 0 &&
- blockSize.height % cellSize.height == 0);
- CV_Assert((winSize.width - blockSize.width) % blockStride.width == 0 &&
- (winSize.height - blockSize.height) % blockStride.height == 0 );
- return (size_t)nbins*
- (blockSize.width/cellSize.width)*
- (blockSize.height/cellSize.height)*
- ((winSize.width - blockSize.width)/blockStride.width + 1)*
- ((winSize.height - blockSize.height)/blockStride.height + 1);
- }
size_t HOGDescriptor::getDescriptorSize() const{ CV_Assert(blockSize.width % cellSize.width == 0 && blockSize.height % cellSize.height == 0); CV_Assert((winSize.width - blockSize.width) % blockStride.width == 0 && (winSize.height - blockSize.height) % blockStride.height == 0 ); return (size_t)nbins* (blockSize.width/cellSize.width)* (blockSize.height/cellSize.height)* ((winSize.width - blockSize.width)/blockStride.width + 1)* ((winSize.height - blockSize.height)/blockStride.height + 1);}
參考文獻
OpenCV中的HOG演算法來源於Histograms of Oriented Gradients for Human Detection, CVPR 2005。詳細的演算法可以參考這個文章。
2.OpenCV中HOG特徵參數個數
http://gz-ricky.blogbus.com/logs/85326280.html
在OpenCV實現的是R-HOG,
即對映像img->視窗window->塊block->細胞單元cell進行向量統計
首先看描述器的建構函式,
我用
HOGDescriptor *desc=newHOGDescriptor(cvSize(40,80),cvSize(10,20),cvSize(5,10),cvSize(5,5),9);
進行測試..
這裡的window為(40, 80), block為(10,
20), block的步進stride是(5, 10),
細胞單元cell是5 * 5像素,
每個cell的長條圖bin是9.
於是,
對每一個cell,
有9個向量
對每一個block,
有2*4個cell,
所以有72個向量
對於window而言,
計算block個數的方法是,
對兩個方向計算 (window_size -block_size)/block_stride + 1,
算得共有7*7
個block, 共有72*49=3528個向量
在搜尋img,
計算圖片特徵的時候,
調用desc->compute(img,w,cvSize(10,20),cvSize(0,0));
其中img是輸入映像, w是儲存向量的vector,
第三個是window的步進,
第四個是padding,
用於填充圖片以適應大小的.
當設定padding為預設(0,0)時,
計算(img_size - window_size) / window_stride +1
不一定為整數
在compute函數中可以看到:
padding.width = (int)alignSize(std::max(padding.width, 0), cacheStride.width);
padding.height = (int)alignSize(std::max(padding.height, 0),cacheStride.height);
即padding的大小會自動適應stride的值.
gz_ricky輸入的圖片是96*160的,
對應了5.6 * 5,
經函數調整後變成6 * 5 =30
所以對這張96*160的圖片,
共有105840個特徵向量
PS.
如果設定了padding的值,
圖片就會先伸展padding*2,
或許是和內部那個paddingTL和paddingBR兩個有關,
即在Top-Left和Button-Right兩個方向都擴充.
計算特徵數方法同上.
hog特徵值會產生以後,
可以轉入svm訓練的階段了