Skip to content

Commit 2af63c2

Browse files
committed
fix py_svm_opencv sample
1 parent 06b0fe3 commit 2af63c2

File tree

2 files changed

+81
-93
lines changed

2 files changed

+81
-93
lines changed

doc/py_tutorials/py_ml/py_svm/py_svm_opencv/py_svm_opencv.markdown

Lines changed: 10 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -17,16 +17,9 @@ vectors.
1717

1818
Here, before finding the HOG, we deskew the image using its second order moments. So we first define
1919
a function **deskew()** which takes a digit image and deskew it. Below is the deskew() function:
20-
@code{.py}
21-
def deskew(img):
22-
m = cv2.moments(img)
23-
if abs(m['mu02']) < 1e-2:
24-
return img.copy()
25-
skew = m['mu11']/m['mu02']
26-
M = np.float32([[1, skew, -0.5*SZ*skew], [0, 1, 0]])
27-
img = cv2.warpAffine(img,M,(SZ, SZ),flags=affine_flags)
28-
return img
29-
@endcode
20+
21+
@snippet samples/python/tutorial_code/ml/py_svm_opencv/hogsvm.py deskew
22+
3023
Below image shows above deskew function applied to an image of zero. Left image is the original
3124
image and right image is the deskewed image.
3225

@@ -38,91 +31,15 @@ gradient is quantized to 16 integer values. Divide this image to four sub-square
3831
sub-square, calculate the histogram of direction (16 bins) weighted with their magnitude. So each
3932
sub-square gives you a vector containing 16 values. Four such vectors (of four sub-squares) together
4033
gives us a feature vector containing 64 values. This is the feature vector we use to train our data.
41-
@code{.py}
42-
def hog(img):
43-
gx = cv2.Sobel(img, cv2.CV_32F, 1, 0)
44-
gy = cv2.Sobel(img, cv2.CV_32F, 0, 1)
45-
mag, ang = cv2.cartToPolar(gx, gy)
46-
47-
# quantizing binvalues in (0...16)
48-
bins = np.int32(bin_n*ang/(2*np.pi))
49-
50-
# Divide to 4 sub-squares
51-
bin_cells = bins[:10,:10], bins[10:,:10], bins[:10,10:], bins[10:,10:]
52-
mag_cells = mag[:10,:10], mag[10:,:10], mag[:10,10:], mag[10:,10:]
53-
hists = [np.bincount(b.ravel(), m.ravel(), bin_n) for b, m in zip(bin_cells, mag_cells)]
54-
hist = np.hstack(hists)
55-
return hist
56-
@endcode
34+
35+
@snippet samples/python/tutorial_code/ml/py_svm_opencv/hogsvm.py hog
36+
5737
Finally, as in the previous case, we start by splitting our big dataset into individual cells. For
5838
every digit, 250 cells are reserved for training data and remaining 250 data is reserved for
59-
testing. Full code is given below:
60-
@code{.py}
61-
import cv2
62-
import numpy as np
63-
64-
SZ=20
65-
bin_n = 16 # Number of bins
66-
67-
68-
affine_flags = cv2.WARP_INVERSE_MAP|cv2.INTER_LINEAR
69-
70-
def deskew(img):
71-
m = cv2.moments(img)
72-
if abs(m['mu02']) < 1e-2:
73-
return img.copy()
74-
skew = m['mu11']/m['mu02']
75-
M = np.float32([[1, skew, -0.5*SZ*skew], [0, 1, 0]])
76-
img = cv2.warpAffine(img,M,(SZ, SZ),flags=affine_flags)
77-
return img
78-
79-
def hog(img):
80-
gx = cv2.Sobel(img, cv2.CV_32F, 1, 0)
81-
gy = cv2.Sobel(img, cv2.CV_32F, 0, 1)
82-
mag, ang = cv2.cartToPolar(gx, gy)
83-
bins = np.int32(bin_n*ang/(2*np.pi)) # quantizing binvalues in (0...16)
84-
bin_cells = bins[:10,:10], bins[10:,:10], bins[:10,10:], bins[10:,10:]
85-
mag_cells = mag[:10,:10], mag[10:,:10], mag[:10,10:], mag[10:,10:]
86-
hists = [np.bincount(b.ravel(), m.ravel(), bin_n) for b, m in zip(bin_cells, mag_cells)]
87-
hist = np.hstack(hists) # hist is a 64 bit vector
88-
return hist
89-
90-
img = cv2.imread('digits.png',0)
91-
92-
cells = [np.hsplit(row,100) for row in np.vsplit(img,50)]
93-
94-
# First half is trainData, remaining is testData
95-
train_cells = [ i[:50] for i in cells ]
96-
test_cells = [ i[50:] for i in cells]
97-
98-
###### Now training ########################
99-
100-
deskewed = [map(deskew,row) for row in train_cells]
101-
hogdata = [map(hog,row) for row in deskewed]
102-
trainData = np.float32(hogdata).reshape(-1,64)
103-
responses = np.float32(np.repeat(np.arange(10),250)[:,np.newaxis])
104-
105-
svm = cv2.ml.SVM_create()
106-
svm.setKernel(cv2.ml.SVM_LINEAR)
107-
svm.setType(cv2.ml.SVM_C_SVC)
108-
svm.setC(2.67)
109-
svm.setGamma(5.383)
110-
111-
svm.train(trainData, cv2.ml.ROW_SAMPLE, responses)
112-
svm.save('svm_data.dat')
113-
114-
###### Now testing ########################
115-
116-
deskewed = [map(deskew,row) for row in test_cells]
117-
hogdata = [map(hog,row) for row in deskewed]
118-
testData = np.float32(hogdata).reshape(-1,bin_n*4)
119-
result = svm.predict(testData)
120-
121-
####### Check Accuracy ########################
122-
mask = result==responses
123-
correct = np.count_nonzero(mask)
124-
print correct*100.0/result.size
125-
@endcode
39+
testing. Full code is given below, you also can download it from [here](https://github.com/opencv/opencv/tree/master/samples/python/tutorial_code/ml/py_svm_opencv/hogsvm.py):
40+
41+
@include samples/python/tutorial_code/ml/py_svm_opencv/hogsvm.py
42+
12643
This particular technique gave me nearly 94% accuracy. You can try different values for various
12744
parameters of SVM to check if higher accuracy is possible. Or you can read technical papers on this
12845
area and try to implement them.
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
import cv2
2+
import numpy as np
3+
4+
SZ=20
5+
bin_n = 16 # Number of bins
6+
7+
8+
affine_flags = cv2.WARP_INVERSE_MAP|cv2.INTER_LINEAR
9+
10+
## [deskew]
11+
def deskew(img):
12+
m = cv2.moments(img)
13+
if abs(m['mu02']) < 1e-2:
14+
return img.copy()
15+
skew = m['mu11']/m['mu02']
16+
M = np.float32([[1, skew, -0.5*SZ*skew], [0, 1, 0]])
17+
img = cv2.warpAffine(img,M,(SZ, SZ),flags=affine_flags)
18+
return img
19+
## [deskew]
20+
21+
## [hog]
22+
def hog(img):
23+
gx = cv2.Sobel(img, cv2.CV_32F, 1, 0)
24+
gy = cv2.Sobel(img, cv2.CV_32F, 0, 1)
25+
mag, ang = cv2.cartToPolar(gx, gy)
26+
bins = np.int32(bin_n*ang/(2*np.pi)) # quantizing binvalues in (0...16)
27+
bin_cells = bins[:10,:10], bins[10:,:10], bins[:10,10:], bins[10:,10:]
28+
mag_cells = mag[:10,:10], mag[10:,:10], mag[:10,10:], mag[10:,10:]
29+
hists = [np.bincount(b.ravel(), m.ravel(), bin_n) for b, m in zip(bin_cells, mag_cells)]
30+
hist = np.hstack(hists) # hist is a 64 bit vector
31+
return hist
32+
## [hog]
33+
34+
img = cv2.imread('digits.png',0)
35+
if img is None:
36+
raise Exception("we need the digits.png image from samples/data here !")
37+
38+
39+
cells = [np.hsplit(row,100) for row in np.vsplit(img,50)]
40+
41+
# First half is trainData, remaining is testData
42+
train_cells = [ i[:50] for i in cells ]
43+
test_cells = [ i[50:] for i in cells]
44+
45+
###### Now training ########################
46+
47+
deskewed = [map(deskew,row) for row in train_cells]
48+
hogdata = [map(hog,row) for row in deskewed]
49+
trainData = np.float32(hogdata).reshape(-1,64)
50+
responses = np.repeat(np.arange(10),250)[:,np.newaxis]
51+
52+
svm = cv2.ml.SVM_create()
53+
svm.setKernel(cv2.ml.SVM_LINEAR)
54+
svm.setType(cv2.ml.SVM_C_SVC)
55+
svm.setC(2.67)
56+
svm.setGamma(5.383)
57+
58+
svm.train(trainData, cv2.ml.ROW_SAMPLE, responses)
59+
svm.save('svm_data.dat')
60+
61+
###### Now testing ########################
62+
63+
deskewed = [map(deskew,row) for row in test_cells]
64+
hogdata = [map(hog,row) for row in deskewed]
65+
testData = np.float32(hogdata).reshape(-1,bin_n*4)
66+
result = svm.predict(testData)[1]
67+
68+
####### Check Accuracy ########################
69+
mask = result==responses
70+
correct = np.count_nonzero(mask)
71+
print correct*100.0/result.size

0 commit comments

Comments
 (0)