2

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

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),我的结果也没有那么好。使用时我需要在预测部分使用 hog.computeMultiscale吗?

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()
4

1 回答 1

2

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

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示例中完成预测:

于 2019-08-18T13:12:57.150 回答