从OpenCV + Python获取HOG图像功能?

lub*_*bar 30 python opencv image-processing

我已经阅读过这篇关于如何使用OpenCV基于HOG的行人检测器的文章: 如何使用OpenCV检测和跟踪人员?

我想用HOG来检测图像中的其他类型的对象(不仅仅是行人).但是,HOGDetectMultiScale的Python绑定似乎无法访问实际的HOG功能.

有没有办法使用Python + OpenCV直接从任何图像中提取HOG功能?

小智 152

在python opencv中你可以像这样计算猪:

 import cv2
 hog = cv2.HOGDescriptor()
 im = cv2.imread(sample)
 h = hog.compute(im)
Run Code Online (Sandbox Code Playgroud)

  • 我想知道为什么这个答案没有发现更受欢迎. (7认同)
  • 我想知道完全一样的事情.道具. (2认同)

mdi*_*lip 41

1.获取内置文档: python控制台上的以下命令将帮助您了解类HOGDescriptor的结构:

 import cv2; 
 help(cv2.HOGDescriptor())
Run Code Online (Sandbox Code Playgroud)

2.实施例编号:下面是一个代码片段来初始化不同参数的cv2.HOGDescriptor(I这里所用的术语是被OpenCV的文档中良好定义的标准条款这里):

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)
Run Code Online (Sandbox Code Playgroud)

3.推理:得到的猪的描述符将具有以下维度:9个方向X(获得1个归一化的4个角块+获得2个归一化的边缘上的6x4块+获得4个归一化的6x6块)= 1764.因为我仅给出hog.compute()的一个位置.

4.另一种初始化方法是xml文件,它包含所有参数值:

hog = cv2.HOGDescriptor("hog.xml")
Run Code Online (Sandbox Code Playgroud)

要获取xml文件,可以执行以下操作:

hog = cv2.HOGDescriptor()
hog.save("hog.xml")
Run Code Online (Sandbox Code Playgroud)

并编辑xml文件中的相应参数值.


pix*_*lou 11

这是一个仅使用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()
Run Code Online (Sandbox Code Playgroud)

我已经使用HOG描述符计算和可视化来理解数据布局并将循环矢量化为组.


car*_*arl 10

如果你想要HOG功能的快速Python代码,我已经将代码移植到Cython:https://github.com/cvondrick/pyvision/blob/master/vision/features.pyx

  • 看起来您的代码每个块输出13个数值,而DPM纸张每个块输出32个数字条目.你能否给出一个关于差异的2线摘要? (5认同)

omo*_*tto 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
Run Code Online (Sandbox Code Playgroud)

问候.


pea*_*kxu -12

我不建议使用 HOG 特征来检测行人以外的物体。在 Dalal 和 Triggs 最初的 HOG 论文中,他们特别提到,他们的检测器是围绕行人检测构建的,允许四肢有很大的自由度,同时使用人体周围的强烈结构提示。

相反,请尝试查看 OpenCV 的HaarDetectObjects您可以在这里学习如何训练您自己的级联。

  • 这不是问题的答案。HOG 描述符与 HOG 检测器不同。描述符是通过计算 HoG 特征在图像块中提供的签名。如果可以收集 HoG 特征的正向和负向训练示例,那么很容易使用 libsvm 或 scikits.learn 来训练 SVM 分类器来识别新的 HoG 特征。这对于检测人类以外的各种形状和物体来说已经非常成功。我目前正在研究使用 OpenCV Python 访问 HoG 描述符,如果我弄清楚了,我会回信。 (10认同)
  • 在计算机视觉文献中,HOG 特征被广泛使用并且非常成功,特别是作为可变形零件模型的构建块。我从未见过有人在任何严肃的物体检测工作中使用 Haar 特征。 (3认同)