2011-05-22 1086 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