forked from robwhess/opensift
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathalg2.py
More file actions
executable file
·119 lines (104 loc) · 3.45 KB
/
alg2.py
File metadata and controls
executable file
·119 lines (104 loc) · 3.45 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
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import os, sys, subprocess, math
class Averager:
def __init__(self):
self._sum = 0.
self._count = 0
self._array = []
def add(self, val):
self._sum += val
self._array.append(val)
self._count += 1
def avg(self):
return round(self._sum / self._count, 2) if self._count > 0 else 0
def stdev(self):
if self._count > 0:
mean = self._sum / self._count
sum2 = sum([ (mean - x)**2 for x in self._array])
return math.sqrt(sum2 / self._count)
def maxVal(self):
return max(self._array) if len(self._array) > 0 else 0
class SiftMatcher:
def __init__(self, databaseDirectory):
self._databaseDirectory = databaseDirectory
self._features = dict()
self._addSifts()
self._comparator = 'bin/comp'
self._siftfeat = 'bin/siftfeat'
def _addSifts(self):
for fileOrDir in os.listdir(self._databaseDirectory):
_fileOrDir = self._databaseDirectory + os.path.sep + fileOrDir
if os.path.isdir(_fileOrDir):
self._features[fileOrDir] = []
for siftFile in os.listdir(_fileOrDir):
self._features[fileOrDir].append(_fileOrDir + os.path.sep + siftFile)
def makeCompStructure(self):
compStructure = dict()
for key in self._features.iterkeys():
compStructure[key] = Averager()
return compStructure
def _findBestMatch(self, matches, strategy):
if strategy == 'max':
bestGroupName = None
bestAvg = -1;
for group, avg in matches.iteritems():
if avg.maxVal() > bestAvg:
bestAvg = avg.maxVal()
bestGroupName = group
return (bestGroupName, bestAvg)
elif strategy == 'avg':
bestGroupName = None
bestAvg = -1;
for group, avg in matches.iteritems():
if avg.avg() > bestAvg:
bestAvg = avg.avg()
bestGroupName = group
return (bestGroupName, bestAvg)
elif strategy == 'stdev':
bestGroupName = None
bestAvg = -1;
for group, avg in matches.iteritems():
if avg.stdev() > bestAvg:
bestAvg = avg.stdev()
bestGroupName = group
return (bestGroupName, round(bestAvg, 2))
elif strategy == 'avg-stdev':
ranking = []
for group, avg in matches.iteritems():
ranking.append((group, avg))
ranking.sort(key=lambda tup: -(tup[1]).avg())
ranking = [ (group, avg.stdev()) for group, avg in ranking[:3]]
ranking.sort(key=lambda tup: -tup[1])
return (ranking[0][0], round(ranking[0][1], 2))
elif strategy == 'stdev-avg':
ranking = []
for group, avg in matches.iteritems():
ranking.append((group, avg))
ranking.sort(key=lambda tup: -(tup[1]).stdev())
ranking = [ (group, avg.avg()) for group, avg in ranking[:3]]
ranking.sort(key=lambda tup: -tup[1])
return (ranking[0][0], ranking[0][1])
else:
raise Exception('No strategy')
def match(self, filename, strategy = 'avg'):
matches = self.makeCompStructure()
basename = os.path.splitext(filename)[0]
devNull = open('/dev/null', 'w')
try:
subprocess.check_call([self._siftfeat, filename, '-o'+basename+'.sift', '-x'], stderr=devNull)
except subprocess.CalledProcessError:
print 'Cannot open file'
return ()
for group, files in self._features.iteritems():
for file in files:
try:
val = int(subprocess.check_output([self._comparator, file, basename+'.sift'], stderr=devNull).strip())
matches[group].add(val)
except subprocess.CalledProcessError:
pass
os.remove(basename + '.sift')
return self._findBestMatch(matches, strategy)
if __name__ == '__main__':
matcher = SiftMatcher('CB')
print matcher.match(sys.argv[1])