我读过这篇关于如何使用OpenCV基于HOG的行人探测器的帖子:How can I detect and track people using OpenCV?
我想用HOG来检测图像中的其他类型的物体(不仅仅是行人)。但是, HOGDetectMultiScale 的Python绑定似乎无法访问实际的HOG功能。
有没有办法使用Python + OpenCV直接从任何图像中提取HOG功能?
答案 0 :(得分:143)
在python opencv中,您可以像这样计算hog:
import cv2
hog = cv2.HOGDescriptor()
im = cv2.imread(sample)
h = hog.compute(im)
答案 1 :(得分:38)
<强> 1。获取内置文档: python控制台上的以下命令将帮助您了解类HOGDescriptor的结构:
import cv2;
help(cv2.HOGDescriptor())
<强> 2。示例代码:以下是使用不同参数初始化cv2.HOGDescriptor的代码片段(我在这里使用的术语是在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。推理:生成的hog描述符的维度为: 9个方向X(获得1个归一化的4个角块+获得2个归一化的边缘上的6x4块+获得4个归一化的6x6块)= 1764.因为我只为hog.compute()提供了一个位置。
<强> 4。另一种初始化的方法是来自xml文件,其中包含所有参数值:
hog = cv2.HOGDescriptor("hog.xml")
要获取xml文件,可以执行以下操作:
hog = cv2.HOGDescriptor()
hog.save("hog.xml")
并编辑xml文件中的相应参数值。
答案 2 :(得分:10)
以下是仅使用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来理解数据布局并将循环矢量化为组。
答案 3 :(得分:10)
尽管存在如前面答案中所述的方法:
hog = cv2.HOGDescriptor()
我想发布一个你可以在opencv的examples目录中找到的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
问候。
答案 4 :(得分:7)
如果您想要快速Python代码用于HOG功能,我已将代码移植到Cython:https://github.com/cvondrick/pyvision/blob/master/vision/features.pyx
答案 5 :(得分:1)
我不同意peakxu的论点。最后的HOG探测器“只是”一个刚性线性滤波器。 “物体”(即人)中的任何自由度都会导致探测器中的模糊,并且实际上并未由它处理。这个探测器有一个扩展使用潜在的SVM,它通过在独立部分(即头部,手臂等)之间引入结构约束来明确处理自由度,并允许每个物体多次出现(即正面人和侧面人... )。
关于opencv中的HOG检测器:理论上,您可以上传另一个与功能一起使用的检测器,但您无法自行获取功能。因此,如果您有一个经过训练的探测器(即一个特定类别的线性滤波器),您应该能够将其上传到探测器中,以获得opencv的快速检测性能。它说很容易破解opencv源代码来提供这种访问,并将这个补丁提交给维护者。
答案 6 :(得分:-10)
我不建议使用HOG功能来检测行人以外的物体。在Dalal和Triggs的原始HOG论文中,他们特别提到他们的探测器是围绕行人探测建立的,允许肢体具有显着的自由度,同时在人体周围使用强烈的结构暗示。
相反,请尝试查看OpenCV的HaarDetectObjects。您可以学习如何训练自己的级联here。