我是否需要在 SVM 中计算预测时的历史?



我正在使用以下代码训练我的数据集:

for file in glob.glob('C:*.png'):
image = cv2.imread(file, 1)
image = cv2.resize(img, (60, 120))
hog = cv2.HOGDescriptor((60,120), (8,8), (4,4), (4,4), 9)
hist = hog.compute(image)
samples.append(hist)
labels.append(-1)

我正在使用hist = hog.compute(image).这段代码在训练部分,但是当我做预测部分时:

hog = cv2.HOGDescriptor((60,120), (8,8), (4,4), (4,4), 9)
svm = cv2.ml.SVM_load('svm_data.xml')
sv = svm.getSupportVectors()
rho, alpha, svidx = svm.getDecisionFunction(0)
svm_new = np.append(sv, -rho)
hog.setSVMDetector(svm_new)

我没有使用hist = hog.compute(image),我的结果也不那么好。使用Multiscale时,我需要在预测部分使用 hog.compute 吗?

found, w = hog.detectMultiScale(img,hitThreshold=0,winStride=(8,8),padding=(16,16), scale=1.05, finalThreshold = 2.0,useMeanshiftGrouping=False)

当我尝试使用它时,它会给出一个错误,没有它,我不会得到好的结果。我在训练部分还是在预测部分做错了?

更新:用于训练 SVM 的完整代码:

samples = []
labels = []    
for filename in glob.glob('C:*.png'):
img = cv2.imread(filename, 0)
img = cv2.resize(img, (160, 320))
hog = cv2.HOGDescriptor((160,320), (16,16), (8,8), (8,8), 9)
hist = hog.compute(img)
samples.append(hist)
labels.append(+1)
for file in glob.glob("C:\*.jpg"):
img = cv2.imread(file, 0)
img = cv2.resize(img, (160, 320))
hog = cv2.HOGDescriptor((160,320), (16,16), (8,8), (8,8), 9)
hist = hog.compute(img)
samples.append(hist)
labels.append(-1)
# Convert objects to Numpy Objects
samples = np.float32(samples)
labels = np.array(labels)
# Shuffle Samples
rand = np.random.RandomState(321)
shuffle = rand.permutation(len(samples))
samples = samples[shuffle]
labels = labels[shuffle]
# Create SVM classifier
svm = cv2.ml.SVM_create()
svm.setType(cv2.ml.SVM_C_SVC)
svm.setKernel(cv2.ml.SVM_LINEAR)
# Train
svm.train(samples, cv2.ml.ROW_SAMPLE, labels)
svm.save('C:svm_data.xml')

用于预测的代码:

sample=[]
hog = cv2.HOGDescriptor((160,320), (16,16), (8,8), (8,8), 9)
svm = cv2.ml.SVM_load('C:svm_data.xml')
sv = svm.getSupportVectors()
rho, alpha, svidx = svm.getDecisionFunction(0)
svm_new = np.append(sv, -rho)
hog.setSVMDetector(svm_new)
for file in glob.glob("C:\Test\*.jpg"): 
img = cv2.imread(file, 0) 
img = cv2.resize(img, (160, 320))
hog = cv2.HOGDescriptor((160,320), (16,16), (8,8), (8,8), 9)
found, w = hog.detectMultiScale(img,hitThreshold=0,winStride=(8,8),padding=(16,16), scale=1.05, finalThreshold = 2.0,useMeanshiftGrouping=False)
for (x, y, w, h) in found:
cv2.rectangle(img, (x, y), (x + w, y + h), (255, 0, 0), 2)
cv2.imshow("Image", img)
cv2.waitKey()

根据您的代码,所有示例都属于同一类:

labels.append(-1)

您的 SVM 分类器无法从中学到任何东西。您需要向 SVM 提供正面示例(标记为 1(和负面示例(通常标记为 0 或 -1(。如果您的数据集是平衡的,这将很有帮助:即正面和负面图像的数量大致相同。

在您的 SVM 正确训练后,hog(通过hog.setSVMDetector()(使用hog.detectMultiScale()hog.detect()将"自动"报告正匹配。它结合了两种操作:计算 HOG 描述符并使用提供的 SVM 对其进行分类。此外,hog.detectMultiScale()自动增加图像,并选择性地对重叠检测进行分组。

现在为什么你需要在训练阶段hog.compute(image):这会计算原始的 HOG 描述符。这是分类器的输入。这些描述符只是一堆以特定方式计算的数字,其本身并不表示图像中是否有您要查找的对象。要做出这个决定,你需要某种分类器,而 SVM 只是一个可能的选择。您不必使用它,它通常只会产生非常好的结果,并且作为默认值包含在内。

更新在 OpenCV 示例中查看预测是如何完成的:

最新更新