forked from sightmachine/SimpleCV
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathSURFTracker.py
More file actions
153 lines (118 loc) · 4.51 KB
/
Copy pathSURFTracker.py
File metadata and controls
153 lines (118 loc) · 4.51 KB
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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
from SimpleCV.base import np, itertools
try:
import cv2
except ImportError:
pass
def surfTracker(img, bb, ts, **kwargs):
"""
**DESCRIPTION**
(Dev Zone)
Tracking the object surrounded by the bounding box in the given
image using SURF keypoints.
Warning: Use this if you know what you are doing. Better have a
look at Image.track()
**PARAMETERS**
* *img* - Image - Image to be tracked.
* *bb* - tuple - Bounding Box tuple (x, y, w, h)
* *ts* - TrackSet - SimpleCV.Features.TrackSet.
Optional PARAMETERS:
eps_val - eps for DBSCAN
The maximum distance between two samples for them
to be considered as in the same neighborhood.
min_samples - min number of samples in DBSCAN
The number of samples in a neighborhood for a point
to be considered as a core point.
distance - thresholding KNN distance of each feature
if KNN distance > distance, point is discarded.
**RETURNS**
SimpleCV.Features.Tracking.SURFTracker
**HOW TO USE**
>>> cam = Camera()
>>> ts = []
>>> img = cam.getImage()
>>> bb = (100, 100, 300, 300) # get BB from somewhere
>>> ts = surfTracker(img, bb, ts, eps_val=0.7, distance=150)
>>> while (some_condition_here):
... img = cam.getImage()
... bb = ts[-1].bb
... ts = surfTracker(img, bb, ts, eps_val=0.7, distance=150)
... ts[-1].drawBB()
... img.show()
This is too much confusing. Better use
Image.track() method.
READ MORE:
SURF based Tracker:
Matches keypoints from the template image and the current frame.
flann based matcher is used to match the keypoints.
Density based clustering is used classify points as in-region (of bounding box)
and out-region points. Using in-region points, new bounding box is predicted using
k-means.
"""
eps_val = 0.69
min_samples = 5
distance = 100
for key in kwargs:
if key == 'eps_val':
eps_val = kwargs[key]
elif key == 'min_samples':
min_samples = kwargs[key]
elif key == 'dist':
distance = kwargs[key]
from scipy.spatial import distance as Dis
from sklearn.cluster import DBSCAN
if len(ts) == 0:
# Get template keypoints
bb = (int(bb[0]), int(bb[1]), int(bb[2]), int(bb[3]))
templateImg = img
detector = cv2.FeatureDetector_create("SURF")
descriptor = cv2.DescriptorExtractor_create("SURF")
templateImg_cv2 = templateImg.getNumpyCv2()[bb[1]:bb[1]+bb[3], bb[0]:bb[0]+bb[2]]
tkp = detector.detect(templateImg_cv2)
tkp, td = descriptor.compute(templateImg_cv2, tkp)
else:
templateImg = ts[-1].templateImg
tkp = ts[-1].tkp
td = ts[-1].td
detector = ts[-1].detector
descriptor = ts[-1].descriptor
newimg = img.getNumpyCv2()
# Get image keypoints
skp = detector.detect(newimg)
skp, sd = descriptor.compute(newimg, skp)
if td is None:
print "Descriptors are Empty"
return None
if sd is None:
track = SURFTracker(img, skp, detector, descriptor, templateImg, skp, sd, tkp, td)
return track
# flann based matcher
flann_params = dict(algorithm=1, trees=4)
flann = cv2.flann_Index(sd, flann_params)
idx, dist = flann.knnSearch(td, 1, params={})
del flann
# filter points using distnace criteria
dist = (dist[:,0]/2500.0).reshape(-1,).tolist()
idx = idx.reshape(-1).tolist()
indices = sorted(range(len(dist)), key=lambda i: dist[i])
dist = [dist[i] for i in indices]
idx = [idx[i] for i in indices]
skp_final = []
skp_final_labelled=[]
data_cluster=[]
for i, dis in itertools.izip(idx, dist):
if dis < distance:
skp_final.append(skp[i])
data_cluster.append((skp[i].pt[0], skp[i].pt[1]))
#Use Denstiy based clustering to further fitler out keypoints
n_data = np.asarray(data_cluster)
D = Dis.squareform(Dis.pdist(n_data))
S = 1 - (D/np.max(D))
db = DBSCAN(eps=eps_val, min_samples=min_samples).fit(S)
core_samples = db.core_sample_indices_
labels = db.labels_
for label, i in zip(labels, range(len(labels))):
if label==0:
skp_final_labelled.append(skp_final[i])
track = SURFTrack(img, skp_final_labelled, detector, descriptor, templateImg, skp, sd, tkp, td)
return track
from SimpleCV.Tracking import SURFTrack