Mercurial > hg > nsaunier > 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') |
