-
Notifications
You must be signed in to change notification settings - Fork 25
/
Copy pathbow.py
84 lines (65 loc) · 2.47 KB
/
bow.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
import cv2
import numpy as np
#
# based on :
# http://gilscvblog.wordpress.com/2013/08/23/bag-of-words-models-for-visual-categorization/
#
# for this sample, we'll use the left/right checkerboard shots from samples/cpp.
# admittedly, there's not much sense in training an svm on left vs right checkerboards,
# but it shows the general flow nicely.
#
# since this is using SIFT, you will need the https://github.com/Itseez/opencv_contrib repo
#
# please modify !
datapath="c:/p/opencv/samples/data"
def path(cls,i): # "./left03.jpg"
return "%s/%s%02d.jpg" % (datapath,cls,i+1)
detect = cv2.xfeatures2d.SIFT_create()
extract = cv2.xfeatures2d.SIFT_create()
flann_params = dict(algorithm = 1, trees = 5) # flann enums are missing, FLANN_INDEX_KDTREE=1
matcher = cv2.FlannBasedMatcher(flann_params, {}) # need to pass empty dict (#1329)
## 1.a setup BOW
bow_train = cv2.BOWKMeansTrainer(8) # toy world, you want more.
bow_extract = cv2.BOWImgDescriptorExtractor( extract, matcher )
## try those, please!
#help(bow_train)
#help(bow_extract)
## 1.b add positives and negatives to the bowtrainer, use SIFT DescriptorExtractor
def feature_sift(fn):
im = cv2.imread(fn,0)
return extract.compute(im, detect.detect(im))[1]
for i in range(8):
bow_train.add(feature_sift(path("left", i)))
bow_train.add(feature_sift(path("right",i)))
## 1.c kmeans cluster descriptors to vocabulary
voc = bow_train.cluster()
bow_extract.setVocabulary( voc )
print("bow vocab", np.shape(voc))
## 2.a gather svm training data, use BOWImgDescriptorExtractor
def feature_bow(fn):
im = cv2.imread(fn,0)
return bow_extract.compute(im, detect.detect(im))
traindata, trainlabels = [],[]
for i in range(6): # save first 2 for testing
traindata.extend(feature_bow(path("left", i+2))); trainlabels.append(-1)
traindata.extend(feature_bow(path("right",i+2))); trainlabels.append(1)
print("svm items", len(traindata), len(traindata[0]))
## 2.b create & train the svm
svm = cv2.ml.SVM_create()
svm.train(np.array(traindata), cv2.ml.ROW_SAMPLE, np.array(trainlabels))
## 2.c predict the remaining 2*2 images, use BOWImgDescriptorExtractor again
def predict(fn):
f = feature_bow(fn);
p = svm.predict(f)
print(fn, "\t", p[1][0][0])
for i in range(2): # testing
predict( path("left",i) )
predict( path("right",i) )
"""
bow vocab (8, 128)
svm items 12 8
e:/code/opencv/samples/cpp/left01.jpg -1.0
e:/code/opencv/samples/cpp/right01.jpg 1.0
e:/code/opencv/samples/cpp/left02.jpg -1.0
e:/code/opencv/samples/cpp/right02.jpg 1.0
"""