Mercurial Hosting > traffic-intelligence
comparison scripts/learn-motion-patterns.py @ 952:a9b2beef0db4
loading and assigning motion patterns works
author | Nicolas Saunier <nicolas.saunier@polymtl.ca> |
---|---|
date | Mon, 24 Jul 2017 21:22:18 -0400 |
parents | 2a4f174879dd |
children | 989917b1ed85 |
comparison
equal
deleted
inserted
replaced
951:2a4f174879dd | 952:a9b2beef0db4 |
---|---|
17 parser.add_argument('-n', dest = 'nTrajectories', help = 'number of the object or feature trajectories to load', type = int, default = None) | 17 parser.add_argument('-n', dest = 'nTrajectories', help = 'number of the object or feature trajectories to load', type = int, default = None) |
18 parser.add_argument('-e', dest = 'epsilon', help = 'distance for the similarity of trajectory points', type = float, required = True) | 18 parser.add_argument('-e', dest = 'epsilon', help = 'distance for the similarity of trajectory points', type = float, required = True) |
19 parser.add_argument('--metric', dest = 'metric', help = 'metric for the similarity of trajectory points', default = 'cityblock') # default is manhattan distance | 19 parser.add_argument('--metric', dest = 'metric', help = 'metric for the similarity of trajectory points', default = 'cityblock') # default is manhattan distance |
20 parser.add_argument('-s', dest = 'minSimilarity', help = 'minimum similarity to put a trajectory in a cluster', type = float, required = True) | 20 parser.add_argument('-s', dest = 'minSimilarity', help = 'minimum similarity to put a trajectory in a cluster', type = float, required = True) |
21 parser.add_argument('-c', dest = 'minClusterSize', help = 'minimum cluster size', type = int, default = None) | 21 parser.add_argument('-c', dest = 'minClusterSize', help = 'minimum cluster size', type = int, default = None) |
22 parser.add_argument('--learn', dest = 'learn', help = 'learn', action = 'store_true') | |
22 parser.add_argument('--optimize', dest = 'optimizeCentroid', help = 'recompute centroid at each assignment', action = 'store_true') | 23 parser.add_argument('--optimize', dest = 'optimizeCentroid', help = 'recompute centroid at each assignment', action = 'store_true') |
23 parser.add_argument('--random', dest = 'randomInitialization', help = 'random initialization of clustering algorithm', action = 'store_true') | 24 parser.add_argument('--random', dest = 'randomInitialization', help = 'random initialization of clustering algorithm', action = 'store_true') |
24 parser.add_argument('--subsample', dest = 'positionSubsamplingRate', help = 'rate of position subsampling (1 every n positions)', type = int) | 25 parser.add_argument('--subsample', dest = 'positionSubsamplingRate', help = 'rate of position subsampling (1 every n positions)', type = int) |
25 parser.add_argument('--display', dest = 'display', help = 'display trajectories', action = 'store_true') | 26 parser.add_argument('--display', dest = 'display', help = 'display trajectories', action = 'store_true') |
26 parser.add_argument('--save-similarities', dest = 'saveSimilarities', help = 'save computed similarities (in addition to prototypes)', action = 'store_true') | 27 parser.add_argument('--save-similarities', dest = 'saveSimilarities', help = 'save computed similarities (in addition to prototypes)', action = 'store_true') |
27 parser.add_argument('--save-matches', dest = 'saveMatches', help = 'saves the assignments of the objects (not for features) to the prototypes', action = 'store_true') | 28 parser.add_argument('--save-matches', dest = 'saveMatches', help = 'saves the assignments of the objects (not for features) to the prototypes', action = 'store_true') |
28 #parser.add_argument('--assign', dest = 'assign', help = 'saves the assignments of the objects (not for features) to the prototypes', action = 'store_true') # default is train, but one could want only to assign the objects to the loaded prototypes without learning | 29 parser.add_argument('--assign', dest = 'assign', help = 'assigns the objects to the prototypes and saves them (do not use min cluster size as it will discard prototypes at the beginning if the initial cluster is too small)', action = 'store_true') |
29 | 30 |
30 args = parser.parse_args() | 31 args = parser.parse_args() |
31 | 32 |
32 # use cases | 33 # use cases |
33 # 1. learn proto from one file, save in same or another (with traj) | 34 # 1. learn proto from one file, save in same or another |
34 # 2. load proto, load objects, update proto, save proto | 35 # 2. load proto, load objects, update proto, save proto |
35 # 3. assign objects from one db to proto | 36 # 3. assign objects from one db to proto |
36 # 4. load objects from several files, save in another -> see metadata: site with view and times | 37 # 4. load objects from several files, save in another -> see metadata: site with view and times |
37 # 5. keep prototypes, with positions/velocities, in separate db (keep link to original data through filename, type and index) | 38 # 5. keep prototypes, with positions/velocities, in separate db (keep link to original data through filename, type and index) |
38 | 39 |
39 # TODO add possibility to cluster with velocities | 40 # TODO add possibility to cluster with velocities |
40 # TODO add possibility to start with saved prototypes so that one can incrementally learn from several databases | 41 # TODO add possibilite to load all trajectories and use minclustersize |
41 # save the objects that match the prototypes | 42 # save the objects that match the prototypes |
42 # write an assignment function for objects | 43 # write an assignment function for objects |
43 | 44 |
44 trajectoryType = args.trajectoryType | 45 trajectoryType = args.trajectoryType |
45 prototypeType = args.trajectoryType | 46 prototypeType = args.trajectoryType |
59 | 60 |
60 trajectories = [o.getPositions().asArray().T for o in objects] | 61 trajectories = [o.getPositions().asArray().T for o in objects] |
61 if args.inputPrototypeDatabaseFilename is not None: | 62 if args.inputPrototypeDatabaseFilename is not None: |
62 initialPrototypes = storage.loadPrototypesFromSqlite(args.inputPrototypeDatabaseFilename, True) | 63 initialPrototypes = storage.loadPrototypesFromSqlite(args.inputPrototypeDatabaseFilename, True) |
63 trajectories = [p.getMovingObject().getPositions().asArray().T for p in initialPrototypes]+trajectories | 64 trajectories = [p.getMovingObject().getPositions().asArray().T for p in initialPrototypes]+trajectories |
64 initialPrototypeIndices = range(len(initialPrototypes)) | 65 if len(initialPrototypes) > 0: |
66 initialPrototypeIndices = range(len(initialPrototypes)) | |
67 else: | |
68 initialPrototypeIndices = None | |
65 else: | 69 else: |
66 initialPrototypes = [] | 70 initialPrototypes = [] |
67 initialPrototypeIndices = None | 71 initialPrototypeIndices = None |
68 | 72 |
69 lcss = utils.LCSS(metric = args.metric, epsilon = args.epsilon) | 73 lcss = utils.LCSS(metric = args.metric, epsilon = args.epsilon) |
70 nTrajectories = len(trajectories) | 74 nTrajectories = len(trajectories) |
71 | 75 |
72 similarities = -np.ones((nTrajectories, nTrajectories)) | 76 similarities = -np.ones((nTrajectories, nTrajectories)) |
77 similarityFunc = lambda x,y : lcss.computeNormalized(x, y) | |
73 # the next line can be called again without reinitializing similarities | 78 # the next line can be called again without reinitializing similarities |
74 prototypeIndices, labels = ml.prototypeCluster(trajectories, similarities, args.minSimilarity, lambda x,y : lcss.computeNormalized(x, y), args.minClusterSize, args.optimizeCentroid, args.randomInitialization, args.inputPrototypeDatabaseFilename is not None, initialPrototypeIndices) # assignment is done only if working on the same database, otherwise the matchings will not compare and one has to to matchings on a large scale at once | 79 if args.learn: |
80 prototypeIndices = ml.prototypeCluster(trajectories, similarities, args.minSimilarity, similarityFunc, args.minClusterSize, args.optimizeCentroid, args.randomInitialization, initialPrototypeIndices) | |
81 # assignment is done if explicitly passed as argument or if working on the same database (starting prototypes from scratch and assigning the ) | |
82 # (otherwise the matchings will not compare and one has to to matchings on a large scale at once) | |
75 | 83 |
76 clusterSizes = ml.computeClusterSizes(labels, prototypeIndices, -1) | 84 if args.assign: |
77 print(clusterSizes) | 85 prototypeIndices, labels = ml.assignToPrototypeClusters(trajectories, prototypeIndices, similarities, args.minSimilarity, similarityFunc, args.minClusterSize) |
86 clusterSizes = ml.computeClusterSizes(labels, prototypeIndices, -1) | |
87 print(clusterSizes) | |
78 | 88 |
79 prototypes = [] | 89 if args.learn or args.assign: |
80 for i in prototypeIndices: | 90 prototypes = [] |
81 if i<len(initialPrototypes): | 91 for i in prototypeIndices: |
82 initialPrototypes[i].nMatchings = 0 | 92 if args.assign: |
83 prototypes.append(initialPrototypes[i]) | 93 nMatchings = clusterSizes[i] |
94 else: | |
95 nMatchings = 0 | |
96 if i<len(initialPrototypes): | |
97 initialPrototypes[i].nMatchings += nMatchings | |
98 prototypes.append(initialPrototypes[i]) | |
99 else: | |
100 prototypes.append(moving.Prototype(args.databaseFilename, objects[i-len(initialPrototypes)].getNum(), prototypeType, nMatchings)) | |
101 | |
102 if args.outputPrototypeDatabaseFilename is None: | |
103 outputPrototypeDatabaseFilename = args.databaseFilename | |
84 else: | 104 else: |
85 if args.inputPrototypeDatabaseFilename is None: | 105 outputPrototypeDatabaseFilename = args.outputPrototypeDatabaseFilename |
86 nmatchings = clusterSizes[i] | 106 if args.inputPrototypeDatabaseFilename == args.outputPrototypeDatabaseFilename: |
87 else: | 107 storage.deleteFromSqlite(args.outputPrototypeDatabaseFilename, 'prototype') |
88 nmatchings = 0 | 108 storage.savePrototypesToSqlite(outputPrototypeDatabaseFilename, prototypes) |
89 prototypes.append(moving.Prototype(args.databaseFilename, objects[i].getNum(), prototypeType, nmatchings)) | |
90 | 109 |
91 if args.outputPrototypeDatabaseFilename is None: | 110 if args.saveSimilarities: |
92 outputPrototypeDatabaseFilename = args.databaseFilename | 111 # todo save trajectories and prototypes |
112 np.savetxt(utils.removeExtension(args.databaseFilename)+'-prototype-similarities.txt.gz', similarities, '%.4f') | |
113 | |
114 labelsToProtoIndices = {protoId: i for i, protoId in enumerate(prototypeIndices)} | |
115 if args.assign and args.saveMatches: # or args.assign | |
116 # save in the db that contained originally the data | |
117 # retirer les assignations anterieures? | |
118 storage.savePrototypeAssignmentsToSqlite(args.databaseFilename, objects, [labelsToProtoIndices[l] for l in labels], prototypes) | |
119 | |
120 if args.display and args.assign: | |
121 from matplotlib.pyplot import figure, show, axis | |
122 figure() | |
123 for i,o in enumerate(objects): | |
124 if i not in prototypeIndices: | |
125 if labels[i] < 0: | |
126 o.plot('kx') | |
127 else: | |
128 o.plot(utils.colors[labels[i]]) | |
129 for i in prototypeIndices: | |
130 objects[i].plot(utils.colors[i]+'o') | |
131 axis('equal') | |
132 show() | |
93 else: | 133 else: |
94 outputPrototypeDatabaseFilename = args.outputPrototypeDatabaseFilename | 134 print('Not learning nor assigning: doing nothing') |
95 storage.savePrototypesToSqlite(outputPrototypeDatabaseFilename, prototypes) | |
96 | |
97 if args.saveSimilarities: | |
98 np.savetxt(utils.removeExtension(args.databaseFilename)+'-prototype-similarities.txt.gz', similarities, '%.4f') | |
99 | |
100 labelsToProtoIndices = {protoId: i for i, protoId in enumerate(prototypeIndices)} | |
101 if args.saveMatches: # or args.assign | |
102 # save in the db that contained originally the data | |
103 # retirer les assignations anterieures? | |
104 storage.savePrototypeAssignmentsToSqlite(args.databaseFilename, objects, [labelsToProtoIndices[l] for l in labels], prototypes) | |
105 | |
106 if args.display: | |
107 from matplotlib.pyplot import figure, show, axis | |
108 figure() | |
109 for i,o in enumerate(objects): | |
110 if i not in prototypeIndices: | |
111 if labels[i] < 0: | |
112 o.plot('kx') | |
113 else: | |
114 o.plot(utils.colors[labels[i]]) | |
115 for i in prototypeIndices: | |
116 objects[i].plot(utils.colors[i]+'o') | |
117 axis('equal') | |
118 show() |