无论图像大小如何,都可以计算固定长度的梯度直方图(HOG)

问题描述 投票:0回答:2

我正在训练一个HOG + SVM模型,我的训练数据有各种大小和宽高比。 SVM模型无法在可变大小的列表上进行训练,因此无论图像大小如何,我都希望计算相同长度的梯度直方图。

有一个聪明的方法吗?或者更好地调整图像大小或填充它们?

machine-learning scikit-learn computer-vision
2个回答
1
投票

人们通常在这种情况下做的是以下两件事之一:

  1. 将所有图像(或图像块)的大小调整为固定大小,并从中提取HOG功能。
  2. 使用“Bag of Words / Features”方法,不要调整图像大小。

第一种方法1.很简单,但它有一些问题,2.试图解决。首先,考虑一下hog描述符的作用。它将图像划分为固定长度的单元格,逐个单元地计算梯度以生成逐个单元格的直方图(基于投票)。最后,您将获得所有单元格的连接直方图,这是您的描述符。

所以它有一个问题,因为对象(你想要检测)必须以类似的方式覆盖图像。否则,根据图像内对象的位置,您的描述符看起来会有所不同。

方法2.的工作原理如下:

  1. 从训练集中的正负图像中提取HOG特征。
  2. 使用像k-means这样的聚类算法来定义固定数量的k质心。
  3. 对于数据集中的每个图像,提取HOG要素并将其与元素进行逐元素比较,以创建频率直方图。

使用频率直方图来训练SVM并将其用于分类阶段。这样,位置无关紧要,您将始终拥有固定大小的输入。您还将受益于尺寸的减少。


1
投票

您可以使用cv2.resize()将图像标准化为给定的目标形状,将图像划分为所需的块数,并计算方向的直方图以及幅度。下面是一个简单的实现。

img = cv2.imread(filename,0)
img = cv2.resize(img,(16,16)) #resize the image

gx = cv2.Sobel(img, cv2.CV_32F, 1, 0) #horizontal gradinets
gy = cv2.Sobel(img, cv2.CV_32F, 0, 1) # vertical gradients

mag, ang = cv2.cartToPolar(gx, gy)
bin_n = 16 # Number of bins
# quantizing binvalues in (0-16)
bins = np.int32(bin_n*ang/(2*np.pi))

# divide to 4 sub-squares
s = 8 #block size
bin_cells = bins[:s,:s],bins[s:,:s],bins[:s,s:],bins[s:,s:]
mag_cells = mag[:s,:s], mag[s:,:s], mag[:s,s:], mag[s:,s:]
hists = [np.bincount(b.ravel(), m.ravel(), bin_n) for b, m in zip(bin_cells,mag_cells)] 

hist = np.hstack(hists) #histogram feature data to be fed to SVM model

希望有所帮助!

© www.soinside.com 2019 - 2024. All rights reserved.