Mercurial Hosting > traffic-intelligence
comparison python/storage.py @ 614:5e09583275a4
Merged Nicolas/trafficintelligence into default
author | Mohamed Gomaa <eng.m.gom3a@gmail.com> |
---|---|
date | Fri, 05 Dec 2014 12:13:53 -0500 |
parents | c5406edbcf12 |
children | 5800a87f11ae 0954aaf28231 |
comparison
equal
deleted
inserted
replaced
598:11f96bd08552 | 614:5e09583275a4 |
---|---|
1 #! /usr/bin/env python | 1 #! /usr/bin/env python |
2 # -*- coding: utf-8 -*- | 2 # -*- coding: utf-8 -*- |
3 '''Various utilities to save and load data''' | 3 '''Various utilities to save and load data''' |
4 | 4 |
5 import utils | 5 import utils, moving, events, indicators |
6 import moving | 6 |
7 import sqlite3, logging | |
7 | 8 |
8 __metaclass__ = type | 9 __metaclass__ = type |
9 | 10 |
11 | |
12 commentChar = '#' | |
13 | |
14 delimiterChar = '%'; | |
10 | 15 |
11 ngsimUserTypes = {'twowheels':1, | 16 ngsimUserTypes = {'twowheels':1, |
12 'car':2, | 17 'car':2, |
13 'truck':3} | 18 'truck':3} |
14 | 19 |
15 ######################### | 20 ######################### |
16 # txt files | |
17 ######################### | |
18 | |
19 | |
20 | |
21 ######################### | |
22 # Sqlite | 21 # Sqlite |
23 ######################### | 22 ######################### |
24 | 23 |
25 def writeTrajectoriesToSqlite(objects, outFile, trajectoryType, objectNumbers = -1): | 24 # utils |
25 def printDBError(error): | |
26 print('DB Error: {}'.format(error)) | |
27 | |
28 def dropTables(connection, tableNames): | |
29 'deletes the table with names in tableNames' | |
30 try: | |
31 cursor = connection.cursor() | |
32 for tableName in tableNames: | |
33 cursor.execute('DROP TABLE IF EXISTS '+tableName) | |
34 except sqlite3.OperationalError as error: | |
35 printDBError(error) | |
36 | |
37 # TODO: add test if database connection is open | |
38 # IO to sqlite | |
39 def writeTrajectoriesToSqlite(objects, outputFilename, trajectoryType, objectNumbers = -1): | |
26 """ | 40 """ |
27 This function writers trajectories to a specified sqlite file | 41 This function writers trajectories to a specified sqlite file |
28 @param[in] objects -> a list of trajectories | 42 @param[in] objects -> a list of trajectories |
29 @param[in] trajectoryType - | 43 @param[in] trajectoryType - |
30 @param[out] outFile -> the .sqlite file containting the written objects | 44 @param[out] outputFilename -> the .sqlite file containting the written objects |
31 @param[in] objectNumber : number of objects loaded | 45 @param[in] objectNumber : number of objects loaded |
32 """ | 46 """ |
33 | 47 connection = sqlite3.connect(outputFilename) |
34 import sqlite3 | 48 cursor = connection.cursor() |
35 connection = sqlite3.connect(outFile) | 49 |
36 cursor = connection.cursor() | 50 schema = "CREATE TABLE IF NOT EXISTS \"positions\"(trajectory_id INTEGER,frame_number INTEGER, x_coordinate REAL, y_coordinate REAL, PRIMARY KEY(trajectory_id, frame_number))" |
37 | |
38 schema = "CREATE TABLE \"positions\"(trajectory_id INTEGER,frame_number INTEGER, x_coordinate REAL, y_coordinate REAL, PRIMARY KEY(trajectory_id, frame_number))" | |
39 cursor.execute(schema) | 51 cursor.execute(schema) |
40 | 52 |
41 trajectory_id = 0 | 53 trajectory_id = 0 |
42 frame_number = 0 | 54 frame_number = 0 |
43 if trajectoryType == 'feature': | 55 if trajectoryType == 'feature': |
48 for position in trajectory.getPositions(): | 60 for position in trajectory.getPositions(): |
49 frame_number += 1 | 61 frame_number += 1 |
50 query = "insert into positions (trajectory_id, frame_number, x_coordinate, y_coordinate) values (?,?,?,?)" | 62 query = "insert into positions (trajectory_id, frame_number, x_coordinate, y_coordinate) values (?,?,?,?)" |
51 cursor.execute(query,(trajectory_id,frame_number,position.x,position.y)) | 63 cursor.execute(query,(trajectory_id,frame_number,position.x,position.y)) |
52 | 64 |
53 connection.commit() | 65 connection.commit() |
66 connection.close() | |
67 | |
68 def writeFeaturesToSqlite(objects, outputFilename, trajectoryType, objectNumbers = -1): | |
69 '''write features trajectories maintain trajectory ID,velocities dataset ''' | |
70 connection = sqlite3.connect(outputFilename) | |
71 cursor = connection.cursor() | |
72 | |
73 cursor.execute("CREATE TABLE IF NOT EXISTS \"positions\"(trajectory_id INTEGER,frame_number INTEGER, x_coordinate REAL, y_coordinate REAL, PRIMARY KEY(trajectory_id, frame_number))") | |
74 cursor.execute("CREATE TABLE IF NOT EXISTS \"velocities\"(trajectory_id INTEGER,frame_number INTEGER, x_coordinate REAL, y_coordinate REAL, PRIMARY KEY(trajectory_id, frame_number))") | |
75 | |
76 if trajectoryType == 'feature': | |
77 if type(objectNumbers) == int and objectNumbers == -1: | |
78 for trajectory in objects: | |
79 trajectory_id = trajectory.num | |
80 frame_number = trajectory.timeInterval.first | |
81 for position,velocity in zip(trajectory.getPositions(),trajectory.getVelocities()): | |
82 cursor.execute("insert into positions (trajectory_id, frame_number, x_coordinate, y_coordinate) values (?,?,?,?)",(trajectory_id,frame_number,position.x,position.y)) | |
83 cursor.execute("insert into velocities (trajectory_id, frame_number, x_coordinate, y_coordinate) values (?,?,?,?)",(trajectory_id,frame_number,velocity.x,velocity.y)) | |
84 frame_number += 1 | |
85 | |
86 connection.commit() | |
87 connection.close() | |
88 | |
89 def writePrototypesToSqlite(prototypes,nMatching, outputFilename): | |
90 """ prototype dataset is a dictionary with keys== routes, values== prototypes Ids """ | |
91 connection = sqlite3.connect(outputFilename) | |
92 cursor = connection.cursor() | |
93 | |
94 cursor.execute("CREATE TABLE IF NOT EXISTS \"prototypes\"(prototype_id INTEGER,routeIDstart INTEGER,routeIDend INTEGER, nMatching INTEGER, PRIMARY KEY(prototype_id))") | |
95 | |
96 for route in prototypes.keys(): | |
97 if prototypes[route]!=[]: | |
98 for i in prototypes[route]: | |
99 cursor.execute("insert into prototypes (prototype_id, routeIDstart,routeIDend, nMatching) values (?,?,?,?)",(i,route[0],route[1],nMatching[route][i])) | |
100 | |
101 connection.commit() | |
102 connection.close() | |
103 | |
104 def loadPrototypesFromSqlite(filename): | |
105 """ | |
106 This function loads the prototype file in the database | |
107 It returns a dictionary for prototypes for each route and nMatching | |
108 """ | |
109 prototypes = {} | |
110 nMatching={} | |
111 | |
112 connection = sqlite3.connect(filename) | |
113 cursor = connection.cursor() | |
114 | |
115 try: | |
116 cursor.execute('SELECT * from prototypes order by prototype_id, routeIDstart,routeIDend, nMatching') | |
117 except sqlite3.OperationalError as error: | |
118 utils.printDBError(error) | |
119 return [] | |
120 | |
121 for row in cursor: | |
122 route=(row[1],row[2]) | |
123 if route not in prototypes.keys(): | |
124 prototypes[route]=[] | |
125 prototypes[route].append(row[0]) | |
126 nMatching[row[0]]=row[3] | |
127 | |
128 connection.close() | |
129 return prototypes,nMatching | |
130 | |
131 def writeLabelsToSqlite(labels, outputFilename): | |
132 """ labels is a dictionary with keys: routes, values: prototypes Ids | |
133 """ | |
134 connection = sqlite3.connect(outputFilename) | |
135 cursor = connection.cursor() | |
136 | |
137 cursor.execute("CREATE TABLE IF NOT EXISTS \"labels\"(object_id INTEGER,routeIDstart INTEGER,routeIDend INTEGER, prototype_id INTEGER, PRIMARY KEY(object_id))") | |
138 | |
139 for route in labels.keys(): | |
140 if labels[route]!=[]: | |
141 for i in labels[route]: | |
142 for j in labels[route][i]: | |
143 cursor.execute("insert into labels (object_id, routeIDstart,routeIDend, prototype_id) values (?,?,?,?)",(j,route[0],route[1],i)) | |
144 | |
145 connection.commit() | |
146 connection.close() | |
147 | |
148 def loadLabelsFromSqlite(filename): | |
149 labels = {} | |
150 | |
151 connection = sqlite3.connect(filename) | |
152 cursor = connection.cursor() | |
153 | |
154 try: | |
155 cursor.execute('SELECT * from labels order by object_id, routeIDstart,routeIDend, prototype_id') | |
156 except sqlite3.OperationalError as error: | |
157 utils.printDBError(error) | |
158 return [] | |
159 | |
160 for row in cursor: | |
161 route=(row[1],row[2]) | |
162 p=row[3] | |
163 if route not in labels.keys(): | |
164 labels[route]={} | |
165 if p not in labels[route].keys(): | |
166 labels[route][p]=[] | |
167 labels[route][p].append(row[0]) | |
168 | |
169 connection.close() | |
170 return labels | |
171 | |
172 def writeRoutesToSqlite(Routes, outputFilename): | |
173 """ This function writes the activity path define by start and end IDs""" | |
174 connection = sqlite3.connect(outputFilename) | |
175 cursor = connection.cursor() | |
176 | |
177 cursor.execute("CREATE TABLE IF NOT EXISTS \"routes\"(object_id INTEGER,routeIDstart INTEGER,routeIDend INTEGER, PRIMARY KEY(object_id))") | |
178 | |
179 for route in Routes.keys(): | |
180 if Routes[route]!=[]: | |
181 for i in Routes[route]: | |
182 cursor.execute("insert into routes (object_id, routeIDstart,routeIDend) values (?,?,?)",(i,route[0],route[1])) | |
183 | |
184 connection.commit() | |
185 connection.close() | |
186 | |
187 def loadRoutesFromSqlite(filename): | |
188 Routes = {} | |
189 | |
190 connection = sqlite3.connect(filename) | |
191 cursor = connection.cursor() | |
192 | |
193 try: | |
194 cursor.execute('SELECT * from routes order by object_id, routeIDstart,routeIDend') | |
195 except sqlite3.OperationalError as error: | |
196 utils.printDBError(error) | |
197 return [] | |
198 | |
199 for row in cursor: | |
200 route=(row[1],row[2]) | |
201 if route not in Routes.keys(): | |
202 Routes[route]=[] | |
203 Routes[route].append(row[0]) | |
204 | |
205 connection.close() | |
206 return Routes | |
207 | |
208 def setRoutes(filename, objects): | |
209 connection = sqlite3.connect(filename) | |
210 cursor = connection.cursor() | |
211 for obj in objects: | |
212 cursor.execute('update objects set startRouteID = {} where object_id = {}'.format(obj.startRouteID, obj.getNum())) | |
213 cursor.execute('update objects set endRouteID = {} where object_id = {}'.format(obj.endRouteID, obj.getNum())) | |
214 connection.commit() | |
215 connection.close() | |
216 | |
217 def setRoadUserTypes(filename, objects): | |
218 '''Saves the user types of the objects in the sqlite database stored in filename | |
219 The objects should exist in the objects table''' | |
220 connection = sqlite3.connect(filename) | |
221 cursor = connection.cursor() | |
222 for obj in objects: | |
223 cursor.execute('update objects set road_user_type = {} where object_id = {}'.format(obj.getUserType(), obj.getNum())) | |
224 connection.commit() | |
54 connection.close() | 225 connection.close() |
55 | 226 |
56 def loadPrototypeMatchIndexesFromSqlite(filename): | 227 def loadPrototypeMatchIndexesFromSqlite(filename): |
57 """ | 228 """ |
58 This function loads the prototypes table in the database of name <filename>. | 229 This function loads the prototypes table in the database of name <filename>. |
59 It returns a list of tuples representing matching ids : [(prototype_id, matched_trajectory_id),...] | 230 It returns a list of tuples representing matching ids : [(prototype_id, matched_trajectory_id),...] |
60 """ | 231 """ |
61 matched_indexes = [] | 232 matched_indexes = [] |
62 | 233 |
63 import sqlite3 | |
64 connection = sqlite3.connect(filename) | 234 connection = sqlite3.connect(filename) |
65 cursor = connection.cursor() | 235 cursor = connection.cursor() |
66 | 236 |
67 try: | 237 try: |
68 cursor.execute('SELECT * from prototypes order by prototype_id, trajectory_id_matched') | 238 cursor.execute('SELECT * from prototypes order by prototype_id, trajectory_id_matched') |
69 except sqlite3.OperationalError as err: | 239 except sqlite3.OperationalError as error: |
70 print('DB Error: {0}'.format(err)) | 240 printDBError(error) |
71 return [] | 241 return [] |
72 | 242 |
73 for row in cursor: | 243 for row in cursor: |
74 matched_indexes.append((row[0],row[1])) | 244 matched_indexes.append((row[0],row[1])) |
75 | 245 |
76 connection.close() | 246 connection.close() |
77 return matched_indexes | 247 return matched_indexes |
78 | 248 |
79 def getTrajectoryIdQuery(objectNumbers, trajectoryType): | 249 def getTrajectoryIdQuery(objectNumbers, trajectoryType): |
80 if trajectoryType == 'feature': | 250 if trajectoryType == 'feature': |
81 statementBeginning = ' where trajectory_id' | 251 statementBeginning = 'where trajectory_id ' |
82 elif trajectoryType == 'object': | 252 elif trajectoryType == 'object': |
83 statementBeginning = ' and OF.object_id' | 253 statementBeginning = 'and OF.object_id ' |
254 elif trajectoryType == 'bbtop' or 'bbbottom': | |
255 statementBeginning = 'where object_id ' | |
84 else: | 256 else: |
85 print('no trajectory type was chosen') | 257 print('no trajectory type was chosen') |
86 | 258 |
87 if type(objectNumbers) == int: | 259 if objectNumbers is None: |
88 if objectNumbers == -1: | 260 query = '' |
89 query = '' | 261 elif type(objectNumbers) == int: |
90 else: | 262 query = statementBeginning+'between 0 and {0} '.format(objectNumbers) |
91 query = statementBeginning+' between 0 and {0}'.format(objectNumbers) | |
92 elif type(objectNumbers) == list: | 263 elif type(objectNumbers) == list: |
93 query = statementBeginning+' in ('+', '.join([str(n) for n in objectNumbers])+')' | 264 query = statementBeginning+'in ('+', '.join([str(n) for n in objectNumbers])+') ' |
94 return query | 265 return query |
95 | 266 |
96 def loadTrajectoriesFromTable(connection, tableName, trajectoryType, objectNumbers = -1): | 267 def loadTrajectoriesFromTable(connection, tableName, trajectoryType, objectNumbers = None): |
97 '''Loads trajectories (in the general sense) from the given table | 268 '''Loads trajectories (in the general sense) from the given table |
98 can be positions or velocities | 269 can be positions or velocities |
99 | 270 |
100 returns a moving object''' | 271 returns a moving object''' |
101 import sqlite3 | 272 cursor = connection.cursor() |
102 | 273 |
103 cursor = connection.cursor() | 274 try: |
104 | 275 idQuery = getTrajectoryIdQuery(objectNumbers, trajectoryType) |
105 try: | |
106 if trajectoryType == 'feature': | 276 if trajectoryType == 'feature': |
107 trajectoryIdQuery = getTrajectoryIdQuery(objectNumbers, trajectoryType) | 277 queryStatement = 'SELECT * from '+tableName+' '+idQuery+'ORDER BY trajectory_id, frame_number' |
108 cursor.execute('SELECT * from '+tableName+trajectoryIdQuery+' order by trajectory_id, frame_number') | 278 cursor.execute(queryStatement) |
279 logging.debug(queryStatement) | |
109 elif trajectoryType == 'object': | 280 elif trajectoryType == 'object': |
110 objectIdQuery = getTrajectoryIdQuery(objectNumbers, trajectoryType) | 281 queryStatement = 'SELECT OF.object_id, P.frame_number, avg(P.x_coordinate), avg(P.y_coordinate) from '+tableName+' P, objects_features OF where P.trajectory_id = OF.trajectory_id '+idQuery+'group by OF.object_id, P.frame_number ORDER BY OF.object_id, P.frame_number' |
111 cursor.execute('SELECT OF.object_id, P.frame_number, avg(P.x_coordinate), avg(P.y_coordinate) from '+tableName+' P, objects_features OF where P.trajectory_id = OF.trajectory_id '+objectIdQuery+' group by object_id, frame_number') | 282 cursor.execute(queryStatement) |
283 logging.debug(queryStatement) | |
284 elif trajectoryType in ['bbtop', 'bbbottom']: | |
285 if trajectoryType == 'bbtop': | |
286 corner = 'top_left' | |
287 elif trajectoryType == 'bbbottom': | |
288 corner = 'bottom_right' | |
289 queryStatement = 'SELECT object_id, frame_number, x_'+corner+', y_'+corner+' FROM '+tableName+' '+trajectoryIdQuery+'ORDER BY object_id, frame_number' | |
290 cursor.execute(queryStatement) | |
291 logging.debug(queryStatement) | |
112 else: | 292 else: |
113 print('no trajectory type was chosen') | 293 print('no trajectory type was chosen') |
114 except sqlite3.OperationalError as err: | 294 except sqlite3.OperationalError as error: |
115 print('DB Error: {0}'.format(err)) | 295 printDBError(error) |
116 return [] | 296 return [] |
117 | 297 |
118 objId = -1 | 298 objId = -1 |
119 obj = None | 299 obj = None |
120 objects = [] | 300 objects = [] |
121 for row in cursor: | 301 for row in cursor: |
122 if row[0] != objId: | 302 if row[0] != objId: |
123 objId = row[0] | 303 objId = row[0] |
124 if obj: | 304 if obj != None and obj.length() == obj.positions.length(): |
125 objects.append(obj) | 305 objects.append(obj) |
306 elif obj != None: | |
307 print('Object {} is missing {} positions'.format(obj.getNum(), int(obj.length())-obj.positions.length())) | |
126 obj = moving.MovingObject(row[0], timeInterval = moving.TimeInterval(row[1], row[1]), positions = moving.Trajectory([[row[2]],[row[3]]])) | 308 obj = moving.MovingObject(row[0], timeInterval = moving.TimeInterval(row[1], row[1]), positions = moving.Trajectory([[row[2]],[row[3]]])) |
127 else: | 309 else: |
128 obj.timeInterval.last = row[1] | 310 obj.timeInterval.last = row[1] |
129 obj.positions.addPositionXY(row[2],row[3]) | 311 obj.positions.addPositionXY(row[2],row[3]) |
130 | 312 |
131 if obj: | 313 if obj != None and obj.length() == obj.positions.length(): |
132 objects.append(obj) | 314 objects.append(obj) |
315 elif obj != None: | |
316 print('Object {} is missing {} positions'.format(obj.getNum(), int(obj.length())-obj.positions.length())) | |
133 | 317 |
134 return objects | 318 return objects |
135 | 319 |
136 def loadTrajectoriesFromSqlite(filename, trajectoryType, objectNumbers = -1): | 320 def loadUserTypesFromTable(cursor, trajectoryType, objectNumbers): |
137 '''Loads nObjects or the indices in objectNumbers from the database | 321 objectIdQuery = getTrajectoryIdQuery(objectNumbers, trajectoryType) |
138 TODO: load feature numbers and not average feature trajectories | 322 if objectIdQuery == '': |
139 TODO: other ways of averaging trajectories (load all points, sorted by frame_number and leave the agregation to be done in python) | 323 cursor.execute('SELECT object_id, road_user_type from objects') |
140 ''' | 324 else: |
141 import sqlite3 | 325 cursor.execute('SELECT object_id, road_user_type from objects where '+objectIdQuery[7:]) |
142 | 326 userTypes = {} |
143 connection = sqlite3.connect(filename) # add test if it open | 327 for row in cursor: |
328 userTypes[row[0]] = row[1] | |
329 return userTypes | |
330 | |
331 def loadTrajectoriesFromSqlite(filename, trajectoryType, objectNumbers = None): | |
332 '''Loads the first objectNumbers objects or the indices in objectNumbers from the database''' | |
333 connection = sqlite3.connect(filename) | |
144 | 334 |
145 objects = loadTrajectoriesFromTable(connection, 'positions', trajectoryType, objectNumbers) | 335 objects = loadTrajectoriesFromTable(connection, 'positions', trajectoryType, objectNumbers) |
146 objectVelocities = loadTrajectoriesFromTable(connection, 'velocities', trajectoryType, objectNumbers) | 336 objectVelocities = loadTrajectoriesFromTable(connection, 'velocities', trajectoryType, objectNumbers) |
147 | 337 |
148 if len(objectVelocities) > 0: | 338 if len(objectVelocities) > 0: |
149 for o,v in zip(objects, objectVelocities): | 339 for o,v in zip(objects, objectVelocities): |
150 if o.num == v.num: | 340 if o.getNum() == v.getNum(): |
151 o.velocities = v.positions | 341 o.velocities = v.positions |
342 o.velocities.duplicateLastPosition() # avoid having velocity shorter by one position than positions | |
152 else: | 343 else: |
153 print('Could not match positions {0} with velocities {1}'.format(o.num, v.num)) | 344 print('Could not match positions {0} with velocities {1}'.format(o.getNum(), v.getNum())) |
154 | 345 |
155 if trajectoryType == 'object': | 346 if trajectoryType == 'object': |
156 cursor = connection.cursor() | 347 cursor = connection.cursor() |
157 try: | 348 try: |
349 # attribute feature numbers to objects | |
158 objectIdQuery = getTrajectoryIdQuery(objectNumbers, trajectoryType) | 350 objectIdQuery = getTrajectoryIdQuery(objectNumbers, trajectoryType) |
159 cursor.execute('SELECT P.trajectory_id, OF.object_id from positions P, objects_features OF where P.trajectory_id = OF.trajectory_id '+objectIdQuery+' group by P.trajectory_id order by OF.object_id') | 351 queryStatement = 'SELECT P.trajectory_id, OF.object_id from positions P, objects_features OF where P.trajectory_id = OF.trajectory_id '+objectIdQuery+'group by P.trajectory_id order by OF.object_id' # order is important to group all features per object |
160 | 352 cursor.execute(queryStatement) |
161 # attribute feature numbers to objects | 353 logging.debug(queryStatement) |
162 objId = -1 | 354 |
163 featureNumbers = {} | 355 featureNumbers = {} |
164 for row in cursor: | 356 for row in cursor: |
165 if row[1] != objId: | 357 objId = row[1] |
166 objId = row[1] | 358 if objId not in featureNumbers: |
167 featureNumbers[objId] = [row[0]] | 359 featureNumbers[objId] = [row[0]] |
168 else: | 360 else: |
169 featureNumbers[objId].append(row[0]) | 361 featureNumbers[objId].append(row[0]) |
170 | 362 |
171 for obj in objects: | 363 for obj in objects: |
172 obj.featureNumbers = featureNumbers[obj.num] | 364 obj.featureNumbers = featureNumbers[obj.getNum()] |
173 except sqlite3.OperationalError as err: | 365 |
174 print('DB Error: {0}'.format(err)) | 366 # load userType |
175 return [] | 367 userTypes = loadUserTypesFromTable(cursor, trajectoryType, objectNumbers) |
368 for obj in objects: | |
369 obj.userType = userTypes[obj.getNum()] | |
370 | |
371 except sqlite3.OperationalError as error: | |
372 printDBError(error) | |
373 objects = [] | |
176 | 374 |
177 connection.close() | 375 connection.close() |
178 return objects | 376 return objects |
179 | 377 |
180 def removeObjectsFromSqlite(filename): | 378 def loadGroundTruthFromSqlite(filename, gtType, gtNumbers = None): |
181 'Removes the objects and object_features tables in the filename' | 379 'Loads bounding box annotations (ground truth) from an SQLite ' |
182 import sqlite3 | 380 connection = sqlite3.connect(filename) |
183 connection = sqlite3.connect(filename) | 381 gt = [] |
184 utils.dropTables(connection, ['objects', 'objects_features']) | 382 |
185 connection.close() | 383 if gtType == 'bb': |
186 | 384 topCorners = loadTrajectoriesFromTable(connection, 'bounding_boxes', 'bbtop', gtNumbers) |
385 bottomCorners = loadTrajectoriesFromTable(connection, 'bounding_boxes', 'bbbottom', gtNumbers) | |
386 userTypes = loadUserTypesFromTable(connection.cursor(), 'object', gtNumbers) # string format is same as object | |
387 | |
388 for t, b in zip(topCorners, bottomCorners): | |
389 num = t.getNum() | |
390 if t.getNum() == b.getNum(): | |
391 annotation = moving.BBAnnotation(num, t.getTimeInterval(), t, b, userTypes[num]) | |
392 gt.append(annotation) | |
393 else: | |
394 print ('Unknown type of annotation {}'.format(gtType)) | |
395 | |
396 connection.close() | |
397 return gt | |
398 | |
399 def deleteFromSqlite(filename, dataType): | |
400 'Deletes (drops) some tables in the filename depending on type of data' | |
401 import os | |
402 if os.path.isfile(filename): | |
403 connection = sqlite3.connect(filename) | |
404 if dataType == 'object': | |
405 dropTables(connection, ['objects', 'objects_features']) | |
406 elif dataType == 'interaction': | |
407 dropTables(connection, ['interactions', 'indicators']) | |
408 elif dataType == 'bb': | |
409 dropTables(connection, ['bounding_boxes']) | |
410 else: | |
411 print('Unknown data type {} to delete from database'.format(dataType)) | |
412 connection.close() | |
413 else: | |
414 print('{} does not exist'.format(filename)) | |
415 | |
416 def createInteractionTable(cursor): | |
417 cursor.execute('CREATE TABLE IF NOT EXISTS interactions (id INTEGER PRIMARY KEY, object_id1 INTEGER, object_id2 INTEGER, first_frame_number INTEGER, last_frame_number INTEGER, FOREIGN KEY(object_id1) REFERENCES objects(id), FOREIGN KEY(object_id2) REFERENCES objects(id))') | |
418 | |
419 def createIndicatorTables(cursor): | |
420 # cursor.execute('CREATE TABLE IF NOT EXISTS indicators (id INTEGER PRIMARY KEY, interaction_id INTEGER, indicator_type INTEGER, FOREIGN KEY(interaction_id) REFERENCES interactions(id))') | |
421 # cursor.execute('CREATE TABLE IF NOT EXISTS indicator_values (indicator_id INTEGER, frame_number INTEGER, value REAL, FOREIGN KEY(indicator_id) REFERENCES indicators(id), PRIMARY KEY(indicator_id, frame_number))') | |
422 cursor.execute('CREATE TABLE IF NOT EXISTS indicators (interaction_id INTEGER, indicator_type INTEGER, frame_number INTEGER, value REAL, FOREIGN KEY(interaction_id) REFERENCES interactions(id), PRIMARY KEY(interaction_id, indicator_type, frame_number))') | |
423 | |
424 def saveInteraction(cursor, interaction): | |
425 roadUserNumbers = list(interaction.getRoadUserNumbers()) | |
426 cursor.execute('INSERT INTO interactions VALUES({}, {}, {}, {}, {})'.format(interaction.getNum(), roadUserNumbers[0], roadUserNumbers[1], interaction.getFirstInstant(), interaction.getLastInstant())) | |
427 | |
428 def saveInteractions(filename, interactions): | |
429 'Saves the interactions in the table' | |
430 connection = sqlite3.connect(filename) | |
431 cursor = connection.cursor() | |
432 try: | |
433 createInteractionTable(cursor) | |
434 for inter in interactions: | |
435 saveInteraction(cursor, inter) | |
436 except sqlite3.OperationalError as error: | |
437 printDBError(error) | |
438 connection.commit() | |
439 connection.close() | |
440 | |
441 def saveIndicator(cursor, interactionNum, indicator): | |
442 for instant in indicator.getTimeInterval(): | |
443 if indicator[instant]: | |
444 cursor.execute('INSERT INTO indicators VALUES({}, {}, {}, {})'.format(interactionNum, events.Interaction.indicatorNameToIndices[indicator.getName()], instant, indicator[instant])) | |
445 | |
446 def saveIndicators(filename, interactions, indicatorNames = events.Interaction.indicatorNames): | |
447 'Saves the indicator values in the table' | |
448 connection = sqlite3.connect(filename) | |
449 cursor = connection.cursor() | |
450 try: | |
451 createInteractionTable(cursor) | |
452 createIndicatorTables(cursor) | |
453 for inter in interactions: | |
454 saveInteraction(cursor, inter) | |
455 for indicatorName in indicatorNames: | |
456 indicator = inter.getIndicator(indicatorName) | |
457 if indicator != None: | |
458 saveIndicator(cursor, inter.getNum(), indicator) | |
459 except sqlite3.OperationalError as error: | |
460 printDBError(error) | |
461 connection.commit() | |
462 connection.close() | |
463 | |
464 def loadInteractions(filename): | |
465 '''Loads interaction and their indicators | |
466 | |
467 TODO choose the interactions to load''' | |
468 interactions = [] | |
469 connection = sqlite3.connect(filename) | |
470 cursor = connection.cursor() | |
471 try: | |
472 cursor.execute('select INT.id, INT.object_id1, INT.object_id2, INT.first_frame_number, INT.last_frame_number, IND.indicator_type, IND.frame_number, IND.value from interactions INT, indicators IND where INT.id = IND.interaction_id ORDER BY INT.id, IND.indicator_type') | |
473 interactionNum = -1 | |
474 indicatorTypeNum = -1 | |
475 tmpIndicators = {} | |
476 for row in cursor: | |
477 if row[0] != interactionNum: # save interaction and create new interaction | |
478 if interactionNum >= 0: | |
479 interactions.append(events.Interaction(interactionNum, moving.TimeInterval(row[3],row[4]), roadUserNumbers[0], roadUserNumbers[1])) | |
480 interactions[-1].indicators = tmpIndicators | |
481 tmpIndicators = {} | |
482 interactionNum = row[0] | |
483 roadUserNumbers = row[1:3] | |
484 if indicatorTypeNum != row[5]: | |
485 if indicatorTypeNum >= 0: | |
486 indicatorName = events.Interaction.indicatorNames[indicatorTypeNum] | |
487 tmpIndicators[indicatorName] = indicators.SeverityIndicator(indicatorName, indicatorValues) | |
488 indicatorTypeNum = row[5] | |
489 indicatorValues = {row[6]:row[7]} | |
490 else: | |
491 indicatorValues[row[6]] = row[7] | |
492 if interactionNum >= 0: | |
493 if indicatorTypeNum >= 0: | |
494 indicatorName = events.Interaction.indicatorNames[indicatorTypeNum] | |
495 tmpIndicators[indicatorName] = indicators.SeverityIndicator(indicatorName, indicatorValues) | |
496 interactions.append(events.Interaction(interactionNum, moving.TimeInterval(row[3],row[4]), roadUserNumbers[0], roadUserNumbers[1])) | |
497 interactions[-1].indicators = tmpIndicators | |
498 except sqlite3.OperationalError as error: | |
499 printDBError(error) | |
500 return [] | |
501 connection.close() | |
502 return interactions | |
503 # load first and last object instants | |
504 # CREATE TEMP TABLE IF NOT EXISTS object_instants AS SELECT OF.object_id, min(frame_number) as first_instant, max(frame_number) as last_instant from positions P, objects_features OF where P.trajectory_id = OF.trajectory_id group by OF.object_id order by OF.object_id | |
505 | |
506 def createBoundingBoxTable(filename, invHomography = None): | |
507 '''Create the table to store the object bounding boxes in image space | |
508 ''' | |
509 connection = sqlite3.connect(filename) | |
510 cursor = connection.cursor() | |
511 try: | |
512 cursor.execute('CREATE TABLE IF NOT EXISTS bounding_boxes (object_id INTEGER, frame_number INTEGER, x_top_left REAL, y_top_left REAL, x_bottom_right REAL, y_bottom_right REAL, PRIMARY KEY(object_id, frame_number))') | |
513 cursor.execute('INSERT INTO bounding_boxes SELECT object_id, frame_number, min(x), min(y), max(x), max(y) from ' | |
514 '(SELECT object_id, frame_number, (x*{}+y*{}+{})/w as x, (x*{}+y*{}+{})/w as y from ' | |
515 '(SELECT OF.object_id, P.frame_number, P.x_coordinate as x, P.y_coordinate as y, P.x_coordinate*{}+P.y_coordinate*{}+{} as w from positions P, objects_features OF where P.trajectory_id = OF.trajectory_id)) '.format(invHomography[0,0], invHomography[0,1], invHomography[0,2], invHomography[1,0], invHomography[1,1], invHomography[1,2], invHomography[2,0], invHomography[2,1], invHomography[2,2])+ | |
516 'GROUP BY object_id, frame_number') | |
517 except sqlite3.OperationalError as error: | |
518 printDBError(error) | |
519 connection.commit() | |
520 connection.close() | |
521 | |
522 def loadBoundingBoxTableForDisplay(filename): | |
523 connection = sqlite3.connect(filename) | |
524 cursor = connection.cursor() | |
525 boundingBoxes = {} # list of bounding boxes for each instant | |
526 try: | |
527 cursor.execute('SELECT name FROM sqlite_master WHERE type=\'table\' AND name=\'bounding_boxes\'') | |
528 result = [row for row in cursor] | |
529 if len(result) > 0: | |
530 cursor.execute('SELECT * FROM bounding_boxes') | |
531 for row in cursor: | |
532 boundingBoxes.setdefault(row[1], []).append([moving.Point(row[2], row[3]), moving.Point(row[4], row[5])]) | |
533 except sqlite3.OperationalError as error: | |
534 printDBError(error) | |
535 return boundingBoxes | |
536 connection.close() | |
537 return boundingBoxes | |
538 | |
539 def loadBoundingBoxTable(filename): | |
540 connection = sqlite3.connect(filename) | |
541 cursor = connection.cursor() | |
542 boundingBoxes = [] | |
543 | |
544 try: | |
545 pass | |
546 except sqlite3.OperationalError as error: | |
547 printDBError(error) | |
548 return boundingBoxes | |
549 connection.close() | |
550 return boundingBoxes | |
551 | |
552 | |
553 ######################### | |
554 # txt files | |
555 ######################### | |
556 | |
557 def openCheck(filename, option = 'r', quitting = False): | |
558 '''Open file filename in read mode by default | |
559 and checks it is open''' | |
560 try: | |
561 return open(filename, option) | |
562 except IOError: | |
563 print 'File %s could not be opened.' % filename | |
564 if quitting: | |
565 from sys import exit | |
566 exit() | |
567 return None | |
568 | |
569 def readline(f, commentCharacters = commentChar): | |
570 '''Modified readline function to skip comments | |
571 Can take a list of characters or a string (in will work in both)''' | |
572 s = f.readline() | |
573 while (len(s) > 0) and s[0] in commentCharacters: | |
574 s = f.readline() | |
575 return s.strip() | |
576 | |
577 def getLines(f, commentCharacters = commentChar): | |
578 '''Gets a complete entry (all the lines) in between delimiterChar.''' | |
579 dataStrings = [] | |
580 s = readline(f, commentCharacters) | |
581 while len(s) > 0: | |
582 dataStrings += [s.strip()] | |
583 s = readline(f, commentCharacters) | |
584 return dataStrings | |
585 | |
586 def writeList(filename, l): | |
587 f = openCheck(filename, 'w') | |
588 for x in l: | |
589 f.write('{}\n'.format(x)) | |
590 f.close() | |
591 | |
592 def loadListStrings(filename, commentCharacters = commentChar): | |
593 f = openCheck(filename, 'r') | |
594 result = getLines(f, commentCharacters) | |
595 f.close() | |
596 return result | |
597 | |
598 def getValuesFromINIFile(filename, option, delimiterChar = '=', commentCharacters = commentChar): | |
599 values = [] | |
600 for l in loadListStrings(filename, commentCharacters): | |
601 if l.startswith(option): | |
602 values.append(l.split(delimiterChar)[1].strip()) | |
603 return values | |
604 | |
605 class FakeSecHead(object): | |
606 '''Add fake section header [asection] | |
607 | |
608 from http://stackoverflow.com/questions/2819696/parsing-properties-file-in-python/2819788#2819788 | |
609 use read_file in Python 3.2+ | |
610 ''' | |
611 def __init__(self, fp): | |
612 self.fp = fp | |
613 self.sechead = '[main]\n' | |
614 | |
615 def readline(self): | |
616 if self.sechead: | |
617 try: return self.sechead | |
618 finally: self.sechead = None | |
619 else: return self.fp.readline() | |
620 | |
621 def loadTrajectoriesFromVissimFile(filename, simulationStepsPerTimeUnit, nObjects = -1, warmUpLastInstant = None): | |
622 '''Reads data from VISSIM .fzp trajectory file | |
623 simulationStepsPerTimeUnit is the number of simulation steps per unit of time used by VISSIM | |
624 for example, there seems to be 5 simulation steps per simulated second in VISSIM, | |
625 so simulationStepsPerTimeUnit should be 5, | |
626 so that all times correspond to the number of the simulation step (and can be stored as integers) | |
627 | |
628 Assumed to be sorted over time''' | |
629 objects = {} # dictionary of objects index by their id | |
630 firstInstants = {} | |
631 | |
632 inputfile = openCheck(filename, quitting = True) | |
633 | |
634 # data = pd.read_csv(filename, skiprows=15, delimiter=';') | |
635 # skip header: 15 lines + 1 | |
636 line = readline(inputfile, '*$') | |
637 while len(line) > 0:#for line in inputfile: | |
638 data = line.strip().split(';') | |
639 objNum = int(data[1]) | |
640 instant = int(float(data[0])*simulationStepsPerTimeUnit) | |
641 s = float(data[4]) | |
642 y = float(data[5]) | |
643 lane = data[2]+'_'+data[3] | |
644 if objNum not in firstInstants: | |
645 firstInstants[objNum] = instant | |
646 if warmUpLastInstant == None or firstInstants[objNum] >= warmUpLastInstant: | |
647 if nObjects < 0 or len(objects) < nObjects: | |
648 objects[objNum] = moving.MovingObject(num = objNum, timeInterval = moving.TimeInterval(instant, instant)) | |
649 objects[objNum].curvilinearPositions = moving.CurvilinearTrajectory() | |
650 if (warmUpLastInstant == None or firstInstants[objNum] >= warmUpLastInstant) and objNum in objects: | |
651 objects[objNum].timeInterval.last = instant | |
652 objects[objNum].curvilinearPositions.addPositionSYL(s, y, lane) | |
653 line = readline(inputfile, '*$') | |
654 | |
655 return objects.values() | |
656 | |
187 def loadTrajectoriesFromNgsimFile(filename, nObjects = -1, sequenceNum = -1): | 657 def loadTrajectoriesFromNgsimFile(filename, nObjects = -1, sequenceNum = -1): |
188 '''Reads data from the trajectory data provided by NGSIM project | 658 '''Reads data from the trajectory data provided by NGSIM project |
189 and returns the list of Feature objects''' | 659 and returns the list of Feature objects''' |
190 objects = [] | 660 objects = [] |
191 | 661 |
192 input = utils.openCheck(filename) | 662 inputfile = openCheck(filename, quitting = True) |
193 if not input: | |
194 import sys | |
195 sys.exit() | |
196 | 663 |
197 def createObject(numbers): | 664 def createObject(numbers): |
198 firstFrameNum = int(numbers[1]) | 665 firstFrameNum = int(numbers[1]) |
199 # do the geometry and usertype | 666 # do the geometry and usertype |
200 | 667 |
209 obj.laneNums = [int(numbers[13])] | 676 obj.laneNums = [int(numbers[13])] |
210 obj.precedingVehicles = [int(numbers[14])] # lead vehicle (before) | 677 obj.precedingVehicles = [int(numbers[14])] # lead vehicle (before) |
211 obj.followingVehicles = [int(numbers[15])] # following vehicle (after) | 678 obj.followingVehicles = [int(numbers[15])] # following vehicle (after) |
212 obj.spaceHeadways = [float(numbers[16])] # feet | 679 obj.spaceHeadways = [float(numbers[16])] # feet |
213 obj.timeHeadways = [float(numbers[17])] # seconds | 680 obj.timeHeadways = [float(numbers[17])] # seconds |
214 obj.curvilinearPositions = moving.Trajectory([[float(numbers[5])],[float(numbers[4])]]) # X is the longitudinal coordinate | 681 obj.curvilinearPositions = moving.CurvilinearTrajectory([float(numbers[5])],[float(numbers[4])], obj.laneNums) # X is the longitudinal coordinate |
215 obj.speeds = [float(numbers[11])] | 682 obj.speeds = [float(numbers[11])] |
216 obj.size = [float(numbers[8]), float(numbers[9])] # 8 lengh, 9 width # TODO: temporary, should use a geometry object | 683 obj.size = [float(numbers[8]), float(numbers[9])] # 8 lengh, 9 width # TODO: temporary, should use a geometry object |
217 return obj | 684 return obj |
218 | 685 |
219 numbers = input.readline().strip().split() | 686 numbers = readline(inputfile).strip().split() |
220 if (len(numbers) > 0): | 687 if (len(numbers) > 0): |
221 obj = createObject(numbers) | 688 obj = createObject(numbers) |
222 | 689 |
223 for line in input: | 690 for line in inputfile: |
224 numbers = line.strip().split() | 691 numbers = line.strip().split() |
225 if obj.num != int(numbers[0]): | 692 if obj.getNum() != int(numbers[0]): |
226 # check and adapt the length to deal with issues in NGSIM data | 693 # check and adapt the length to deal with issues in NGSIM data |
227 if (obj.length() != obj.positions.length()): | 694 if (obj.length() != obj.positions.length()): |
228 print 'length pb with object %s (%d,%d)' % (obj.num,obj.length(),obj.positions.length()) | 695 print 'length pb with object %s (%d,%d)' % (obj.getNum(),obj.length(),obj.positions.length()) |
229 obj.last = obj.getFirstInstant()+obj.positions.length()-1 | 696 obj.last = obj.getFirstInstant()+obj.positions.length()-1 |
230 #obj.velocities = utils.computeVelocities(f.positions) # compare norm to speeds ? | 697 #obj.velocities = utils.computeVelocities(f.positions) # compare norm to speeds ? |
231 objects.append(obj) | 698 objects.append(obj) |
232 if (nObjects>0) and (len(objects)>=nObjects): | 699 if (nObjects>0) and (len(objects)>=nObjects): |
233 break | 700 break |
234 obj = createObject(numbers) | 701 obj = createObject(numbers) |
235 else: | 702 else: |
703 obj.laneNums.append(int(numbers[13])) | |
236 obj.positions.addPositionXY(float(numbers[6]), float(numbers[7])) | 704 obj.positions.addPositionXY(float(numbers[6]), float(numbers[7])) |
237 obj.curvilinearPositions.addPositionXY(float(numbers[5]), float(numbers[4])) | 705 obj.curvilinearPositions.addPositionSYL(float(numbers[5]), float(numbers[4]), obj.laneNums[-1]) |
238 obj.speeds.append(float(numbers[11])) | 706 obj.speeds.append(float(numbers[11])) |
239 obj.laneNums.append(int(numbers[13])) | |
240 obj.precedingVehicles.append(int(numbers[14])) | 707 obj.precedingVehicles.append(int(numbers[14])) |
241 obj.followingVehicles.append(int(numbers[15])) | 708 obj.followingVehicles.append(int(numbers[15])) |
242 obj.spaceHeadways.append(float(numbers[16])) | 709 obj.spaceHeadways.append(float(numbers[16])) |
243 obj.timeHeadways.append(float(numbers[17])) | 710 obj.timeHeadways.append(float(numbers[17])) |
244 | 711 |
245 if (obj.size[0] != float(numbers[8])): | 712 if (obj.size[0] != float(numbers[8])): |
246 print 'changed length obj %d' % (f.num) | 713 print 'changed length obj %d' % (obj.getNum()) |
247 if (obj.size[1] != float(numbers[9])): | 714 if (obj.size[1] != float(numbers[9])): |
248 print 'changed width obj %d' % (f.num) | 715 print 'changed width obj %d' % (obj.getNum()) |
249 | 716 |
250 input.close() | 717 inputfile.close() |
251 return objects | 718 return objects |
252 | 719 |
253 def convertNgsimFile(inFile, outFile, append = False, nObjects = -1, sequenceNum = 0): | 720 def convertNgsimFile(inputfile, outputfile, append = False, nObjects = -1, sequenceNum = 0): |
254 '''Reads data from the trajectory data provided by NGSIM project | 721 '''Reads data from the trajectory data provided by NGSIM project |
255 and converts to our current format.''' | 722 and converts to our current format.''' |
256 if append: | 723 if append: |
257 out = open(outFile,'a') | 724 out = openCheck(outputfile,'a') |
258 else: | 725 else: |
259 out = open(outFile,'w') | 726 out = openCheck(outputfile,'w') |
260 nObjectsPerType = [0,0,0] | 727 nObjectsPerType = [0,0,0] |
261 | 728 |
262 features = loadNgsimFile(inFile, sequenceNum) | 729 features = loadNgsimFile(inputfile, sequenceNum) |
263 for f in features: | 730 for f in features: |
264 nObjectsPerType[f.userType-1] += 1 | 731 nObjectsPerType[f.userType-1] += 1 |
265 f.write(out) | 732 f.write(out) |
266 | 733 |
267 print nObjectsPerType | 734 print nObjectsPerType |
268 | 735 |
269 out.close() | 736 out.close() |
737 | |
738 def writePositionsToCsv(f, obj): | |
739 timeInterval = obj.getTimeInterval() | |
740 positions = obj.getPositions() | |
741 curvilinearPositions = obj.getCurvilinearPositions() | |
742 for i in xrange(int(obj.length())): | |
743 p1 = positions[i] | |
744 s = '{},{},{},{}'.format(obj.num,timeInterval[i],p1.x,p1.y) | |
745 if curvilinearPositions != None: | |
746 p2 = curvilinearPositions[i] | |
747 s += ',{},{}'.format(p2[0],p2[1]) | |
748 f.write(s+'\n') | |
749 | |
750 def writeTrajectoriesToCsv(filename, objects): | |
751 f = openCheck(filename, 'w') | |
752 for i,obj in enumerate(objects): | |
753 writePositionsToCsv(f, obj) | |
754 f.close() | |
755 | |
756 | |
757 ######################### | |
758 # Utils to read .ini type text files for configuration, meta data... | |
759 ######################### | |
760 | |
761 class ProcessParameters: | |
762 '''Class for all parameters controlling data processing: input, | |
763 method parameters, etc. for tracking, classification and safety | |
764 | |
765 Note: framerate is already taken into account''' | |
766 | |
767 def loadConfigFile(self, filename): | |
768 from ConfigParser import ConfigParser | |
769 from numpy import loadtxt | |
770 from os import path | |
771 | |
772 config = ConfigParser() | |
773 config.readfp(FakeSecHead(openCheck(filename))) | |
774 self.sectionHeader = config.sections()[0] | |
775 # Tracking/display parameters | |
776 self.videoFilename = config.get(self.sectionHeader, 'video-filename') | |
777 self.databaseFilename = config.get(self.sectionHeader, 'database-filename') | |
778 self.homographyFilename = config.get(self.sectionHeader, 'homography-filename') | |
779 if (path.exists(self.homographyFilename)): | |
780 self.homography = loadtxt(self.homographyFilename) | |
781 else: | |
782 self.homography = None | |
783 self.intrinsicCameraFilename = config.get(self.sectionHeader, 'intrinsic-camera-filename') | |
784 if (path.exists(self.intrinsicCameraFilename)): | |
785 self.intrinsicCameraMatrix = loadtxt(self.intrinsicCameraFilename) | |
786 else: | |
787 self.intrinsicCameraMatrix = None | |
788 distortionCoefficients = getValuesFromINIFile(filename, 'distortion-coefficients', '=') | |
789 self.distortionCoefficients = [float(x) for x in distortionCoefficients] | |
790 self.undistortedImageMultiplication = config.getfloat(self.sectionHeader, 'undistorted-size-multiplication') | |
791 self.undistort = config.getboolean(self.sectionHeader, 'undistort') | |
792 self.firstFrameNum = config.getint(self.sectionHeader, 'frame1') | |
793 self.videoFrameRate = config.getfloat(self.sectionHeader, 'video-fps') | |
794 | |
795 # Classification parameters | |
796 | |
797 | |
798 # Safety parameters | |
799 self.maxPredictedSpeed = config.getfloat(self.sectionHeader, 'max-predicted-speed')/3.6/self.videoFrameRate | |
800 self.predictionTimeHorizon = config.getfloat(self.sectionHeader, 'prediction-time-horizon')*self.videoFrameRate | |
801 self.collisionDistance = config.getfloat(self.sectionHeader, 'collision-distance') | |
802 self.crossingZones = config.getboolean(self.sectionHeader, 'crossing-zones') | |
803 self.predictionMethod = config.get(self.sectionHeader, 'prediction-method') | |
804 self.nPredictedTrajectories = config.getint(self.sectionHeader, 'npredicted-trajectories') | |
805 self.maxNormalAcceleration = config.getfloat(self.sectionHeader, 'max-normal-acceleration')/self.videoFrameRate**2 | |
806 self.maxNormalSteering = config.getfloat(self.sectionHeader, 'max-normal-steering')/self.videoFrameRate | |
807 self.minExtremeAcceleration = config.getfloat(self.sectionHeader, 'min-extreme-acceleration')/self.videoFrameRate**2 | |
808 self.maxExtremeAcceleration = config.getfloat(self.sectionHeader, 'max-extreme-acceleration')/self.videoFrameRate**2 | |
809 self.maxExtremeSteering = config.getfloat(self.sectionHeader, 'max-extreme-steering')/self.videoFrameRate | |
810 self.useFeaturesForPrediction = config.getboolean(self.sectionHeader, 'use-features-prediction') | |
811 | |
812 def __init__(self, filename = None): | |
813 if filename != None: | |
814 self.loadConfigFile(filename) | |
815 | |
816 class SceneParameters: | |
817 def __init__(self, config, sectionName): | |
818 from ConfigParser import NoOptionError | |
819 from ast import literal_eval | |
820 try: | |
821 self.sitename = config.get(sectionName, 'sitename') | |
822 self.databaseFilename = config.get(sectionName, 'data-filename') | |
823 self.homographyFilename = config.get(sectionName, 'homography-filename') | |
824 self.calibrationFilename = config.get(sectionName, 'calibration-filename') | |
825 self.videoFilename = config.get(sectionName, 'video-filename') | |
826 self.frameRate = config.getfloat(sectionName, 'framerate') | |
827 self.date = datetime.strptime(config.get(sectionName, 'date'), datetimeFormat) # 2011-06-22 11:00:39 | |
828 self.translation = literal_eval(config.get(sectionName, 'translation')) # = [0.0, 0.0] | |
829 self.rotation = config.getfloat(sectionName, 'rotation') | |
830 self.duration = config.getint(sectionName, 'duration') | |
831 except NoOptionError as e: | |
832 print(e) | |
833 print('Not a section for scene meta-data') | |
834 | |
835 @staticmethod | |
836 def loadConfigFile(filename): | |
837 from ConfigParser import ConfigParser | |
838 config = ConfigParser() | |
839 config.readfp(openCheck(filename)) | |
840 configDict = dict() | |
841 for sectionName in config.sections(): | |
842 configDict[sectionName] = SceneParameters(config, sectionName) | |
843 return configDict | |
844 | |
270 | 845 |
271 if __name__ == "__main__": | 846 if __name__ == "__main__": |
272 import doctest | 847 import doctest |
273 import unittest | 848 import unittest |
274 suite = doctest.DocFileSuite('tests/storage.txt') | 849 suite = doctest.DocFileSuite('tests/storage.txt') |