我需要在 SVM 的预测时间计算 hist 吗?
Posted
技术标签:
【中文标题】我需要在 SVM 的预测时间计算 hist 吗?【英文标题】:Do I need to calculate hist at prediction time in SVM? 【发布时间】:2019-12-20 22:59:27 【问题描述】:我正在使用以下代码训练我的数据集:
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()
【问题讨论】:
【参考方案1】:根据您的代码,所有示例都属于同一类:
labels.append(-1)
您的 SVM 分类器无法从中学到任何东西。您需要向 SVM 呈现正样本(标记为 1)和负样本(通常标记为 0 或 -1)。如果您的数据集是平衡的,这将很有帮助:即正面和负面图像的数量大致相同。
在正确训练您的 SVM 并使用 hog.detectMultiScale()
或 hog.detect()
使 hog
意识到它(通过 hog.setSVMDetector()
)后,将“自动”报告正匹配。它结合了两个操作:计算 HOG 描述符并使用提供的 SVM 对它们进行分类。此外hog.detectMultiScale()
自动增加图像并可选择对重叠检测进行分组。
现在为什么在训练阶段需要hog.compute(image)
:它会计算原始 HOG 描述符。这是分类器的输入。这些描述符只是以特定方式计算的一堆数字,它们本身并不表示您在图像中是否存在您正在寻找的对象。要做出这个决定,你需要某种分类器,而 SVM 只是一个可能的选择。您不必使用它,它通常只会产生非常好的结果,并且作为默认设置包含在内。
更新 看看如何在 OpenCV example 中完成预测:
【讨论】:
我用代码更新了问题,我正在做+1部分,我只在我的代码中添加了-1部分,我的数据集是平衡的,负数和正数都是1500。 代码运行良好,但结果一点也不好,大约 0%,这就是为什么我问我是否需要在hog.compute(image)
的某个地方工作
答案仍然是否定的。您的代码看起来没问题。可能是您搜索的对象太复杂。尝试以下操作:在对样本进行洗牌后,获取前 80% 的数据并训练您的 SVM。其余时间运行svm.predict()
。将结果与标签进行比较。它会告诉你你的分类器有多好。
hist
的尺寸是多少?如果不是一维向量,应该使用.ravel()
我正在使用 '.ravel()' 它只是不在上面的代码中。因为我也尝试过不使用 ravel。我正在检测眉毛。以上是关于我需要在 SVM 的预测时间计算 hist 吗?的主要内容,如果未能解决你的问题,请参考以下文章