2011-05-22 315 views
24

我讀過這篇文章瞭解如何使用OpenCV中的基於HOG行人檢測:How can I detect and track people using OpenCV?從OpenCV + Python獲取HOG圖像特徵?

我想用HOG用於檢測圖像中的其他類型的對象(不只是行人)。但是,HOGDetectMultiScale的Python綁定似乎不能訪問實際的HOG功能。

有什麼方法可以使用Python + OpenCV直接從任何圖像中提取HOG特徵?

+0

我發現這個有用的MATLAB庫:http://vision.ucsd.edu/~pdollar/toolbox/doc/index.html – lubar 2012-08-08 04:06:56

回答

-9

我不建議使用HOG功能檢測行人以外的物體。在Dalal和Triggs的原始HOG論文中,他們特別提到他們的探測器是圍繞行人檢測而建立的,以便在肢體周圍使用強烈的結構暗示時允許四肢具有顯着的自由度。

請嘗試查看OpenCV的HaarDetectObjects。你可以學習如何訓練你自己的瀑布here

+1

OpenCV HOG檢測器(即訓練好的SVM)是行人專用的,但我已經成功地使用HOG特徵來訓練用於更一般對象類別的探測器。到目前爲止,我一直在使用[這個MATLAB包](http://www.mathworks.com/matlabcentral/fileexchange/28689-hog-descriptor-for-matlab),但會對OpenCV解決方案感興趣。 – lubar 2011-05-25 17:32:47

+7

這不是問題的答案。 HOG描述符與HOG檢測器不同。描述符是通過計算HoG功能在圖像補丁中提供的簽名。如果可以收集HoG特徵的正面和負面訓練示例,則可以使用libsvm或scikits.learn輕鬆訓練SVM分類器以對新的HoG特徵進行識別。這已經非常成功地用於檢測超出人體形狀的各種形狀和物體。我目前正在研究如何使用OpenCV Python訪問HoG描述符,如果我弄清楚它會回寫。 – ely 2011-09-07 04:46:50

+2

在計算機視覺文獻中,HOG特徵被廣泛使用並且相當成功,特別是作爲可變形零件模型的構件。我從來沒有見過任何人在任何嚴肅的物體檢測工作中使用哈爾功能。 – 2013-10-21 19:06:51

1

我不同意peakxu的論點。 HOG探測器到底是「剛」的剛性線性濾波器。 「物體」(即人)的任何自由度都會導致檢測器發生模糊,並且實際上沒有被它處理。這種探測器有一個擴展,它使用隱式SVM,它通過在獨立部分(即頭部,手臂等)之間引入結構約束來明確處理自由度,並允許每個對象有多個外觀(即正面人物和側面人物。 )。

關於opencv中的HOG檢測器:從理論上講,您可以上傳另一個檢測器來與這些功能一起使用,但是您無法自行獲取這些功能。因此,如果您擁有訓練有素的探測器(即特定類別的線性濾波器),您應該可以將其上傳到探測器,以獲得opencv的快速檢測性能。他表示應該很容易地破解opencv源代碼來提供這種訪問權限,並將這個補丁提交給維護者。

112

在Python中的OpenCV可以計算的生豬是這樣的:

import cv2 
hog = cv2.HOGDescriptor() 
im = cv2.imread(sample) 
h = hog.compute(im) 
+7

我想知道爲什麼這個答案沒有找到更多的人氣。 – 2014-11-30 21:24:59

+2

我想知道完全一樣的東西。道具。 – SetSlapShot 2015-02-19 14:34:05

+1

我在想同樣的事情! – 2015-03-10 15:14:10

28

1.獲取內置文檔:您的python控制檯上的以下命令將幫助您瞭解HOGDescriptor類的結構:

import cv2; 
help(cv2.HOGDescriptor()) 

2.實施例編號:這裏是一個代碼片段來初始化不同參數的cv2.HOGDescriptor(I這裏所用的術語是被OpenCV的文檔here在良好定義的標準術語):

import cv2 
image = cv2.imread("test.jpg",0) 
winSize = (64,64) 
blockSize = (16,16) 
blockStride = (8,8) 
cellSize = (8,8) 
nbins = 9 
derivAperture = 1 
winSigma = 4. 
histogramNormType = 0 
L2HysThreshold = 2.0000000000000001e-01 
gammaCorrection = 0 
nlevels = 64 
hog = cv2.HOGDescriptor(winSize,blockSize,blockStride,cellSize,nbins,derivAperture,winSigma, 
         histogramNormType,L2HysThreshold,gammaCorrection,nlevels) 
#compute(img[, winStride[, padding[, locations]]]) -> descriptors 
winStride = (8,8) 
padding = (8,8) 
locations = ((10,20),) 
hist = hog.compute(image,winStride,padding,locations) 

3.推理:由此產生的描述符將具有以下維度: 9個方向X(4個角塊獲得1歸一化+ 6×4塊獲得2個歸一化+ 6×6個塊獲得4個歸一化)= 1764。只給hog.compute()提供一個位置。

4。還有一個初始化方式是它包含了所有的參數值的XML文件:

hog = cv2.HOGDescriptor("hog.xml") 

爲了得到一個XML文件可以做到以下幾點:

hog = cv2.HOGDescriptor() 
hog.save("hog.xml") 

,並在XML文件中編輯相應的參數值。

7

這裏是僅使用OpenCV的一個解決方案:

import numpy as np 
import cv2 
import matplotlib.pyplot as plt 

img = cv2.cvtColor(cv2.imread("/home/me/Downloads/cat.jpg"), 
        cv2.COLOR_BGR2GRAY) 

cell_size = (8, 8) # h x w in pixels 
block_size = (2, 2) # h x w in cells 
nbins = 9 # number of orientation bins 

# winSize is the size of the image cropped to an multiple of the cell size 
hog = cv2.HOGDescriptor(_winSize=(img.shape[1] // cell_size[1] * cell_size[1], 
            img.shape[0] // cell_size[0] * cell_size[0]), 
         _blockSize=(block_size[1] * cell_size[1], 
            block_size[0] * cell_size[0]), 
         _blockStride=(cell_size[1], cell_size[0]), 
         _cellSize=(cell_size[1], cell_size[0]), 
         _nbins=nbins) 

n_cells = (img.shape[0] // cell_size[0], img.shape[1] // cell_size[1]) 
hog_feats = hog.compute(img)\ 
       .reshape(n_cells[1] - block_size[1] + 1, 
         n_cells[0] - block_size[0] + 1, 
         block_size[0], block_size[1], nbins) \ 
       .transpose((1, 0, 2, 3, 4)) # index blocks by rows first 
# hog_feats now contains the gradient amplitudes for each direction, 
# for each cell of its group for each group. Indexing is by rows then columns. 

gradients = np.zeros((n_cells[0], n_cells[1], nbins)) 

# count cells (border cells appear less often across overlapping groups) 
cell_count = np.full((n_cells[0], n_cells[1], 1), 0, dtype=int) 

for off_y in range(block_size[0]): 
    for off_x in range(block_size[1]): 
     gradients[off_y:n_cells[0] - block_size[0] + off_y + 1, 
        off_x:n_cells[1] - block_size[1] + off_x + 1] += \ 
      hog_feats[:, :, off_y, off_x, :] 
     cell_count[off_y:n_cells[0] - block_size[0] + off_y + 1, 
        off_x:n_cells[1] - block_size[1] + off_x + 1] += 1 

# Average gradients 
gradients /= cell_count 

# Preview 
plt.figure() 
plt.imshow(img, cmap='gray') 
plt.show() 

bin = 5 # angle is 360/nbins * direction 
plt.pcolor(gradients[:, :, bin]) 
plt.gca().invert_yaxis() 
plt.gca().set_aspect('equal', adjustable='box') 
plt.colorbar() 
plt.show() 

我已經使用HOG descriptor computation and visualization理解數據的佈局和矢量的遍歷組。

7

儘管在以前的答案說,存在的方法的事實:

生豬= cv2.HOGDescriptor()

我想張貼的OpenCV的例子Python實現,你可以找到目錄中,希望能夠了解HOG功能:

def hog(img): 
    gx = cv2.Sobel(img, cv2.CV_32F, 1, 0) 
    gy = cv2.Sobel(img, cv2.CV_32F, 0, 1) 
    mag, ang = cv2.cartToPolar(gx, gy) 
    bin_n = 16 # Number of bins 
    bin = np.int32(bin_n*ang/(2*np.pi)) 

    bin_cells = [] 
    mag_cells = [] 

    cellx = celly = 8 

    for i in range(0,img.shape[0]/celly): 
     for j in range(0,img.shape[1]/cellx): 
      bin_cells.append(bin[i*celly : i*celly+celly, j*cellx : j*cellx+cellx]) 
      mag_cells.append(mag[i*celly : i*celly+celly, j*cellx : j*cellx+cellx]) 

    hists = [np.bincount(b.ravel(), m.ravel(), bin_n) for b, m in zip(bin_cells, mag_cells)] 
    hist = np.hstack(hists) 

    # transform to Hellinger kernel 
    eps = 1e-7 
    hist /= hist.sum() + eps 
    hist = np.sqrt(hist) 
    hist /= norm(hist) + eps 

    return hist 

問候。

+0

什麼是你的代碼中使用的「規範」函數? – 2017-03-09 23:14:55

+0

@克萊門特˚F對不起,我要補充的導入庫聲明: _ **從numpy.linalg進口規範** _ 在這裏你有功能說明的鏈接: [鏈接](https://開頭docs.scipy.org/doc/numpy/reference/generated/numpy.linalg.norm.html) – omotto 2017-03-10 07:14:53

+0

@omotto請你詳細解釋一下上面的算法。 – 2017-05-06 07:35:15