Mercurial > hg > nsaunier > traffic-intelligence
comparison python/storage.py @ 834:119c4efe6398
added option to load subsampled trajectories
| author | Nicolas Saunier <nicolas.saunier@polymtl.ca> |
|---|---|
| date | Thu, 30 Jun 2016 14:19:59 -0400 |
| parents | a8ff35e6fb43 |
| children | 5a68779d7777 |
comparison
equal
deleted
inserted
replaced
| 833:8d1dd771aeb3 | 834:119c4efe6398 |
|---|---|
| 5 import utils, moving, events, indicators, shutil | 5 import utils, moving, events, indicators, shutil |
| 6 from base import VideoFilenameAddable | 6 from base import VideoFilenameAddable |
| 7 | 7 |
| 8 from os import path | 8 from os import path |
| 9 import sqlite3, logging | 9 import sqlite3, logging |
| 10 from numpy import log, min as npmin, max as npmax, round as npround, array, sum as npsum, loadtxt | 10 from numpy import log, min as npmin, max as npmax, round as npround, array, sum as npsum, loadtxt, floor as npfloor, ceil as npceil |
| 11 from pandas import read_csv, merge | 11 from pandas import read_csv, merge |
| 12 | 12 |
| 13 | 13 |
| 14 commentChar = '#' | 14 commentChar = '#' |
| 15 | 15 |
| 143 else: | 143 else: |
| 144 print('objectNumbers {} are not a known type ({})'.format(objectNumbers, type(objectNumbers))) | 144 print('objectNumbers {} are not a known type ({})'.format(objectNumbers, type(objectNumbers))) |
| 145 query = '' | 145 query = '' |
| 146 return query | 146 return query |
| 147 | 147 |
| 148 def loadTrajectoriesFromTable(connection, tableName, trajectoryType, objectNumbers = None): | 148 def loadTrajectoriesFromTable(connection, tableName, trajectoryType, objectNumbers = None, timeStep = None): |
| 149 '''Loads trajectories (in the general sense) from the given table | 149 '''Loads trajectories (in the general sense) from the given table |
| 150 can be positions or velocities | 150 can be positions or velocities |
| 151 | 151 |
| 152 returns a moving object''' | 152 returns a moving object''' |
| 153 cursor = connection.cursor() | 153 cursor = connection.cursor() |
| 155 try: | 155 try: |
| 156 objectCriteria = getObjectCriteria(objectNumbers) | 156 objectCriteria = getObjectCriteria(objectNumbers) |
| 157 queryStatement = None | 157 queryStatement = None |
| 158 if trajectoryType == 'feature': | 158 if trajectoryType == 'feature': |
| 159 queryStatement = 'SELECT * from '+tableName | 159 queryStatement = 'SELECT * from '+tableName |
| 160 if objectNumbers is not None: | 160 if objectNumbers is not None and timeStep is not None: |
| 161 queryStatement += ' WHERE trajectory_id '+objectCriteria+' AND frame_number%{} = 0'.format(timeStep) | |
| 162 elif objectNumbers is not None: | |
| 161 queryStatement += ' WHERE trajectory_id '+objectCriteria | 163 queryStatement += ' WHERE trajectory_id '+objectCriteria |
| 164 elif timeStep is not None: | |
| 165 queryStatement += ' WHERE frame_number%{} = 0'.format(timeStep) | |
| 162 queryStatement += ' ORDER BY trajectory_id, frame_number' | 166 queryStatement += ' ORDER BY trajectory_id, frame_number' |
| 163 elif trajectoryType == 'object': | 167 elif trajectoryType == 'object': |
| 164 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' | 168 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' |
| 165 if objectNumbers is not None: | 169 if objectNumbers is not None: |
| 166 queryStatement += ' and OF.object_id '+objectCriteria | 170 queryStatement += ' AND OF.object_id '+objectCriteria |
| 171 if timeStep is not None: | |
| 172 queryStatement += ' AND P.frame_number%{} = 0'.format(timeStep) | |
| 167 queryStatement += ' GROUP BY OF.object_id, P.frame_number ORDER BY OF.object_id, P.frame_number' | 173 queryStatement += ' GROUP BY OF.object_id, P.frame_number ORDER BY OF.object_id, P.frame_number' |
| 168 elif trajectoryType in ['bbtop', 'bbbottom']: | 174 elif trajectoryType in ['bbtop', 'bbbottom']: |
| 169 if trajectoryType == 'bbtop': | 175 if trajectoryType == 'bbtop': |
| 170 corner = 'top_left' | 176 corner = 'top_left' |
| 171 elif trajectoryType == 'bbbottom': | 177 elif trajectoryType == 'bbbottom': |
| 172 corner = 'bottom_right' | 178 corner = 'bottom_right' |
| 173 queryStatement = 'SELECT object_id, frame_number, x_'+corner+', y_'+corner+' FROM '+tableName | 179 queryStatement = 'SELECT object_id, frame_number, x_'+corner+', y_'+corner+' FROM '+tableName |
| 174 if objectNumbers is not None: | 180 if objectNumbers is not None and timeStep is not None: |
| 181 queryStatement += ' WHERE object_id '+objectCriteria+' AND frame_number%{} = 0'.format(timeStep) | |
| 182 elif objectNumbers is not None: | |
| 175 queryStatement += ' WHERE object_id '+objectCriteria | 183 queryStatement += ' WHERE object_id '+objectCriteria |
| 184 elif timeStep is not None: | |
| 185 queryStatement += ' WHERE frame_number%{} = 0'.format(timeStep) | |
| 176 queryStatement += ' ORDER BY object_id, frame_number' | 186 queryStatement += ' ORDER BY object_id, frame_number' |
| 177 else: | 187 else: |
| 178 print('Unknown trajectory type {}'.format(trajectoryType)) | 188 print('Unknown trajectory type {}'.format(trajectoryType)) |
| 179 if queryStatement is not None: | 189 if queryStatement is not None: |
| 180 cursor.execute(queryStatement) | 190 cursor.execute(queryStatement) |
| 187 obj = None | 197 obj = None |
| 188 objects = [] | 198 objects = [] |
| 189 for row in cursor: | 199 for row in cursor: |
| 190 if row[0] != objId: | 200 if row[0] != objId: |
| 191 objId = row[0] | 201 objId = row[0] |
| 192 if obj is not None and obj.length() == obj.positions.length(): | 202 if obj is not None and (obj.length() == obj.positions.length() or (timeStep is not None and npceil(obj.length()/timeStep) == obj.positions.length())): |
| 193 objects.append(obj) | 203 objects.append(obj) |
| 194 elif obj is not None: | 204 elif obj is not None: |
| 195 print('Object {} is missing {} positions'.format(obj.getNum(), int(obj.length())-obj.positions.length())) | 205 print('Object {} is missing {} positions'.format(obj.getNum(), int(obj.length())-obj.positions.length())) |
| 196 obj = moving.MovingObject(row[0], timeInterval = moving.TimeInterval(row[1], row[1]), positions = moving.Trajectory([[row[2]],[row[3]]])) | 206 obj = moving.MovingObject(row[0], timeInterval = moving.TimeInterval(row[1], row[1]), positions = moving.Trajectory([[row[2]],[row[3]]])) |
| 197 else: | 207 else: |
| 198 obj.timeInterval.last = row[1] | 208 obj.timeInterval.last = row[1] |
| 199 obj.positions.addPositionXY(row[2],row[3]) | 209 obj.positions.addPositionXY(row[2],row[3]) |
| 200 | 210 |
| 201 if obj is not None and obj.length() == obj.positions.length(): | 211 if obj is not None and (obj.length() == obj.positions.length() or (timeStep is not None and npceil(obj.length()/timeStep) == obj.positions.length())): |
| 202 objects.append(obj) | 212 objects.append(obj) |
| 203 elif obj is not None: | 213 elif obj is not None: |
| 204 print('Object {} is missing {} positions'.format(obj.getNum(), int(obj.length())-obj.positions.length())) | 214 print('Object {} is missing {} positions'.format(obj.getNum(), int(obj.length())-obj.positions.length())) |
| 205 | 215 |
| 206 return objects | 216 return objects |
| 214 userTypes = {} | 224 userTypes = {} |
| 215 for row in cursor: | 225 for row in cursor: |
| 216 userTypes[row[0]] = row[1] | 226 userTypes[row[0]] = row[1] |
| 217 return userTypes | 227 return userTypes |
| 218 | 228 |
| 219 def loadTrajectoriesFromSqlite(filename, trajectoryType, objectNumbers = None, withFeatures = False): | 229 def loadTrajectoriesFromSqlite(filename, trajectoryType, objectNumbers = None, withFeatures = False, timeStep = None): |
| 220 '''Loads the trajectories (in the general sense, | 230 '''Loads the trajectories (in the general sense, |
| 221 either features, objects (feature groups) or bounding box series) | 231 either features, objects (feature groups) or bounding box series) |
| 222 The number loaded is either the first objectNumbers objects, | 232 The number loaded is either the first objectNumbers objects, |
| 223 or the indices in objectNumbers from the database''' | 233 or the indices in objectNumbers from the database''' |
| 224 connection = sqlite3.connect(filename) | 234 connection = sqlite3.connect(filename) |
| 225 | 235 |
| 226 objects = loadTrajectoriesFromTable(connection, 'positions', trajectoryType, objectNumbers) | 236 objects = loadTrajectoriesFromTable(connection, 'positions', trajectoryType, objectNumbers, timeStep) |
| 227 objectVelocities = loadTrajectoriesFromTable(connection, 'velocities', trajectoryType, objectNumbers) | 237 objectVelocities = loadTrajectoriesFromTable(connection, 'velocities', trajectoryType, objectNumbers, timeStep) |
| 228 | 238 |
| 229 if len(objectVelocities) > 0: | 239 if len(objectVelocities) > 0: |
| 230 for o,v in zip(objects, objectVelocities): | 240 for o,v in zip(objects, objectVelocities): |
| 231 if o.getNum() == v.getNum(): | 241 if o.getNum() == v.getNum(): |
| 232 o.velocities = v.positions | 242 o.velocities = v.positions |
| 264 | 274 |
| 265 if withFeatures: | 275 if withFeatures: |
| 266 nFeatures = 0 | 276 nFeatures = 0 |
| 267 for obj in objects: | 277 for obj in objects: |
| 268 nFeatures = max(nFeatures, max(obj.featureNumbers)) | 278 nFeatures = max(nFeatures, max(obj.featureNumbers)) |
| 269 features = loadTrajectoriesFromSqlite(filename, 'feature', nFeatures+1) | 279 features = loadTrajectoriesFromSqlite(filename, 'feature', nFeatures+1, timeStep = timeStep) |
| 270 for obj in objects: | 280 for obj in objects: |
| 271 obj.setFeatures(features) | 281 obj.setFeatures(features) |
| 272 | 282 |
| 273 except sqlite3.OperationalError as error: | 283 except sqlite3.OperationalError as error: |
| 274 printDBError(error) | 284 printDBError(error) |
| 368 connection.close() | 378 connection.close() |
| 369 | 379 |
| 370 def loadPrototypesFromSqlite(filename): | 380 def loadPrototypesFromSqlite(filename): |
| 371 pass | 381 pass |
| 372 | 382 |
| 373 def loadBBMovingObjectsFromSqlite(filename, objectType = 'bb', objectNumbers = None): | 383 def loadBBMovingObjectsFromSqlite(filename, objectType = 'bb', objectNumbers = None, timeStep = None): |
| 374 '''Loads bounding box moving object from an SQLite | 384 '''Loads bounding box moving object from an SQLite |
| 375 (format of SQLite output by the ground truth annotation tool | 385 (format of SQLite output by the ground truth annotation tool |
| 376 or Urban Tracker | 386 or Urban Tracker |
| 377 | 387 |
| 378 Load descriptions?''' | 388 Load descriptions?''' |
| 379 connection = sqlite3.connect(filename) | 389 connection = sqlite3.connect(filename) |
| 380 objects = [] | 390 objects = [] |
| 381 | 391 |
| 382 if objectType == 'bb': | 392 if objectType == 'bb': |
| 383 topCorners = loadTrajectoriesFromTable(connection, 'bounding_boxes', 'bbtop', objectNumbers) | 393 topCorners = loadTrajectoriesFromTable(connection, 'bounding_boxes', 'bbtop', objectNumbers, timeStep) |
| 384 bottomCorners = loadTrajectoriesFromTable(connection, 'bounding_boxes', 'bbbottom', objectNumbers) | 394 bottomCorners = loadTrajectoriesFromTable(connection, 'bounding_boxes', 'bbbottom', objectNumbers, timeStep) |
| 385 userTypes = loadUserTypesFromTable(connection.cursor(), 'object', objectNumbers) # string format is same as object | 395 userTypes = loadUserTypesFromTable(connection.cursor(), 'object', objectNumbers) # string format is same as object |
| 386 | 396 |
| 387 for t, b in zip(topCorners, bottomCorners): | 397 for t, b in zip(topCorners, bottomCorners): |
| 388 num = t.getNum() | 398 num = t.getNum() |
| 389 if t.getNum() == b.getNum(): | 399 if t.getNum() == b.getNum(): |
