I am training my dataset with the below code:
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)
I am using hist = hog.compute(image)
. This code is in the training part, but when I do the prediction part:
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)
I am not using hist = hog.compute(image)
, and my results are not as good. Do I need to use hog.compute in prediction part while using Multiscale
?
found, w = hog.detectMultiScale(img,hitThreshold=0,winStride=(8,8),padding=(16,16), scale=1.05, finalThreshold = 2.0,useMeanshiftGrouping=False)
When I try to use it, it gives an error, and without it, I am not getting good results. Am I doing wrong in the training part or in the prediction part?
Update: Complete code using for training 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')
Code using for Prediction:
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()
According to your code, all the samples belong to the same class:
Your SVM classifier can't learn anything from this. You need to present to SVM both positive examples (labeled as 1) and negative ones (usually labeled as 0 or -1). It would be helpful if your dataset is balanced: that is amount of positive and negative images is roughly the same.
After your SVM is trained properly, and
hog
is made aware of it (byhog.setSVMDetector()
) usinghog.detectMultiScale()
orhog.detect()
will "automatically" report positive matches. It combines two operation: calculates HOG descriptors and classifies them using provided SVM. In additionhog.detectMultiScale()
automatically increases the image and optionally groups the overlapped detections.Now why you need
hog.compute(image)
on the training phase: this calculates raw HOG descriptors. This is the input to your classifier. Those descriptors is just a bunch of numbers calculated in specific way, and by themselves do not indicate if there is an object that you are looking for in the image. To make this decision, you need some kind of a classifier, and SVM is just a possible choice. You do not have to use it, it just usually produces very good results, and is included as a default.Update See how prediction is done in the OpenCV example: