How to use a custom SVM with HOGDescriptor, in Python [closed]

asked 2015-03-03 07:30:24 -0600

NebuK gravatar image

updated 2015-03-16 04:10:09 -0600

Hi,

this is a bit against the Idea here, but as its a topic i struggeled quite a bit, i’ll post it here anyways.

The problem is using a custom SVM in HOGDescriptor.detect[MultiScale]. Now, HOGDescriptor wants a float numpy array with mystery content for setSVMDetector(…). As to what the mystery-content is, we can look at the source: https://github.com/Itseez/opencv/blob...

Now the problem is how to get the list of SVs and rho — while CvSVM seems to have facilities for this, they’re not exposed to Python. This is where a dirty but working hack comes in: Saving the SVM to XML, then parsing that file to get the parameters. Something like:

<collect your training data in descs and labels in resps as usual>
import xml.etree.ElementTree as ET
svm = cv2.SVM()
svm.train_auto(descs, resps, None, None, params=svm_params, k_fold=5)

svm.save("svm.xml")
tree = ET.parse('svm.xml')
root = tree.getroot()
# now this is really dirty, but after ~3h of fighting OpenCV its what happens :-)
SVs = root.getchildren()[0].getchildren()[-2].getchildren()[0] 
rho = float( root.getchildren()[0].getchildren()[-1].getchildren()[0].getchildren()[1].text )
svmvec = [float(x) for x in re.sub( '\s+', ' ', SVs.text ).strip().split(' ')]
svmvec.append(-rho)
pickle.dump(svmvec, open("svm.pickle", 'w'))

And for using it:

img = cv2.imread(inp)
hog = cv2.HOGDescriptor((32,64), (16,16), (8,8), (8,8), 9)
svm = pickle.load(open("svm.pickle"))
hog.setSVMDetector( np.array(svm) )
del svm
found, w = hog.detectMultiScale(img)

this seems to work for me — so if anyone ever needs a custom SVM for HOG in OpenCV-Python without touching C++, i hope you can find this post!

Best Regards, hope this helps! Dario Ernst

edit retag flag offensive reopen merge delete

Closed for the following reason question is not relevant or outdated by sturkmen
close date 2020-10-07 01:01:35.565639

Comments

Thank you! I've been searching for a solution to training a SVM for the python HOG descriptors but I wasn't getting much.

You're a lifesaver!

crd319 gravatar imagecrd319 ( 2015-03-03 19:01:27 -0600 )edit

One question: what is ET? Guess some xml parser, but for completeness please add your import to the example. Thx!

Guanta gravatar imageGuanta ( 2015-03-04 07:36:12 -0600 )edit
1

Guanta: The ET stands for ElementTree, which is a very useful python XML parser. They typical import call is:

import xml.etree.ElementTree as ET.

crd319 gravatar imagecrd319 ( 2015-03-04 14:54:24 -0600 )edit

Dario: I tried implementing the code you suggested, but instead of getting actual targets I always seem to get a single return in the center of the image, regardless of the input. Do you know anything that might cause such a thing to happen?

crd319 gravatar imagecrd319 ( 2015-03-09 17:45:19 -0600 )edit

Added the import — crd319 was right, thanks for telling quicker than me :-). @crd319: What exactly happens with those svm vectors in the depths of HOG.detectMultiScale is a big mytho for me too — i fear i can not be of much help. A few things i would check is the strides, meanShift can get funky results too. Also, i had „glitches” with too small scales happening where i’d always get full-frame BBoxes. But … all of those i didn’t understand why. Sorry!

NebuK gravatar imageNebuK ( 2015-03-16 04:13:58 -0600 )edit

Questions. What is re in the line: 'svmvec = [float(x) for x in re.sub( '\s+', ' ', SVs.text ).strip().split(' ')]'?

ljcljc gravatar imageljcljc ( 2015-04-11 22:35:21 -0600 )edit

The regexpression submodule, s. https://docs.python.org/2/library/re....

Guanta gravatar imageGuanta ( 2015-04-13 06:02:57 -0600 )edit

Hi, I'm following your tutorial and it works(only training), when it came to testing, I got error at hog.setSVMDetector( np.array(svm) , " hog.setSVMDetector(np.array(svm)) cv2.error: C:\build\master_winpack-bindings-win32-vc14-static\opencv\modules\objdetect\src\hog.cpp:117: error: (-215) checkDetectorSize() in function cv::HOGDescriptor::setSVMDetector) " My system opencv : 3.2.0 os : windows 7 64 bit python : 2.7

adamaulia gravatar imageadamaulia ( 2017-04-26 06:11:38 -0600 )edit

@adamaulia, make sure that the winSize that you're using for your hog detector has the same dimensions as the training images you are using

mechaddict gravatar imagemechaddict ( 2017-08-23 19:19:45 -0600 )edit

@gravatar, I too got the same error as "penCV Error: Assertion failed (checkDetectorSize())", i had made sure that the winSize of hog is same dimension as the training image, and i also checked the size of np.array(svm) it shows 15553, while the trained descriptor of train image sample size is 15552, i think adding rho increased the length of np.array(svm), can you suggest a solution for the error.

krishnasai gravatar imagekrishnasai ( 2018-02-08 03:33:40 -0600 )edit