使用OpenCV在Python中进行HOG训练和检测

4
我在使用Python、OpenCV 3.1和HOG进行有用检测时遇到了问题。尽管我编写的代码没有出现错误,但经过训练的HOG/SVM组合无法在测试图像上进行检测。
从OpenCV示例和其他Stack Overflow讨论中,我已经开发出了以下方法。
win_size = (64, 64)
block_size = (16, 16)
block_stride = (8, 8)
cell_size = (8, 8)
nbins = 9
deriv_aperture = 1
win_sigma = 4.
histogram_norm_type = 0
l2_hys_threshold = 2.0000000000000001e-01
gamma_correction = 0
nlevels = 64

hog = cv2.HOGDescriptor(win_size,
                        block_size,
                        block_stride,
                        cell_size,
                        nbins,
                        deriv_aperture,
                        win_sigma,
                        histogram_norm_type,
                        l2_hys_threshold,
                        gamma_correction,
                        nlevels)

window_stride = (8, 8)
padding = (8, 8)
locations = ((0, 0),)

histograms = []
# not showing the loop here but
# create histograms for 600 positive and 600 negative images
# all images are of size 64x64
histograms.append(np.transpose(hog.compute(roi, window_stride, padding, locations)))

training_data = np.concatenate(histograms)
classifications = np.array([1] * 600 + [0] * 600)

svm = cv2.ml.SVM_create()
svm.setType(cv2.ml.SVM_C_SVC)
svm.setKernel(cv2.ml.SVM_LINEAR)
svm.setC(0.01)
svm.setTermCriteria((cv2.TermCriteria_MAX_ITER, 100, 1e-6))

svm.train(training_data, cv2.ml.ROW_SAMPLE, classifications)

# testing
test_img = cv2.imread('test_image.jpg')
svmvec = svm.getSupportVectors()[0]
rho = -svm.getDecisionFunction(0)[0]
svmvec = np.append(svmvec, rho)
hog.setSVMDetector(svmvec)
found, w = hog.detectMultiScale(test_img)

在每个测试中,found是一个居中于图像中的单个矩形,与测试图像中的正样本位置不一致。

我已经尝试了许多不同的参数组合,基于 Stack Overflow 的答案和其他 OpenCV 示例和讨论。但它们都没有改变结果。


详细而有组织的问题解释应该得到奖励。我可以问一下,为什么你只使用 **svm.getSupportVectors()[0]**? - Bedir Yilmaz
2个回答

0

我认为你需要使用所有的支持向量。所以问题不在于你的训练代码,而是你的测试。

svm.train(training_data, cv2.ml.ROW_SAMPLE, classifications)

在训练时,您使用所有数据进行训练,但在测试时,只使用分类器的一小部分。

svmvec = svm.getSupportVectors()[0]

修改这一行,你就会少一个问题。


0
单个矩形被创建在中心的原因是因为检测器将几乎所有区域都分类为“人类”。 默认情况下,detectMultiScale抑制矩形的重叠。因此,您只能看到中心的单个矩形。 您可以使用detectMultiScale的finalThreshold选项关闭此抑制。
hogParams = { 'finalThreshold': 0}
found, w = hog.detectMultiScale(test_img, **hogParams)

默认情况下,此参数设置为2。 您可以看到几乎所有区域都被矩形颜色填充。

我对这种“错误分类”的答案很简单,就是更改标签的顺序。

classifications = np.array([0] * 600 + [1] * 600)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接