Mercurial Hosting > traffic-intelligence
diff python/storage.py @ 708:a37c565f4b68
merged dev
author | Nicolas Saunier <nicolas.saunier@polymtl.ca> |
---|---|
date | Wed, 22 Jul 2015 14:17:44 -0400 |
parents | f83d125d0c55 |
children | 523eda2fafd4 |
line wrap: on
line diff
--- a/python/storage.py Wed Jul 22 14:17:19 2015 -0400 +++ b/python/storage.py Wed Jul 22 14:17:44 2015 -0400 @@ -6,6 +6,7 @@ from base import VideoFilenameAddable import sqlite3, logging +from numpy import log, min as npmin, max as npmax, round as npround, array, sum as npsum, loadtxt commentChar = '#' @@ -289,22 +290,16 @@ connection.close() return matched_indexes -def getTrajectoryIdQuery(objectNumbers, trajectoryType): - if trajectoryType == 'feature': - statementBeginning = 'where trajectory_id ' - elif trajectoryType == 'object': - statementBeginning = 'and OF.object_id ' - elif trajectoryType == 'bbtop' or 'bbbottom': - statementBeginning = 'where object_id ' - else: - print('no trajectory type was chosen') - +def getObjectCriteria(objectNumbers): if objectNumbers is None: query = '' elif type(objectNumbers) == int: - query = statementBeginning+'between 0 and {0} '.format(objectNumbers) + query = 'between 0 and {0}'.format(objectNumbers-1) elif type(objectNumbers) == list: - query = statementBeginning+'in ('+', '.join([str(n) for n in objectNumbers])+') ' + query = 'in ('+', '.join([str(n) for n in objectNumbers])+')' + else: + print('objectNumbers {} are not a known type ({})'.format(objectNumbers, type(objectNumbers))) + query = '' return query def loadTrajectoriesFromTable(connection, tableName, trajectoryType, objectNumbers = None): @@ -315,13 +310,19 @@ cursor = connection.cursor() try: - idQuery = getTrajectoryIdQuery(objectNumbers, trajectoryType) + objectCriteria = getObjectCriteria(objectNumbers) if trajectoryType == 'feature': - queryStatement = 'SELECT * from '+tableName+' '+idQuery+'ORDER BY trajectory_id, frame_number' + queryStatement = 'SELECT * from '+tableName + if objectNumbers is not None: + queryStatement += ' where trajectory_id '+objectCriteria + queryStatement += ' ORDER BY trajectory_id, frame_number' cursor.execute(queryStatement) logging.debug(queryStatement) elif trajectoryType == 'object': - 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' + 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' + if objectNumbers is not None: + queryStatement += ' and OF.object_id '+objectCriteria + queryStatement += ' group by OF.object_id, P.frame_number ORDER BY OF.object_id, P.frame_number' cursor.execute(queryStatement) logging.debug(queryStatement) elif trajectoryType in ['bbtop', 'bbbottom']: @@ -329,7 +330,10 @@ corner = 'top_left' elif trajectoryType == 'bbbottom': corner = 'bottom_right' - queryStatement = 'SELECT object_id, frame_number, x_'+corner+', y_'+corner+' FROM '+tableName+' '+idQuery+'ORDER BY object_id, frame_number' + queryStatement = 'SELECT object_id, frame_number, x_'+corner+', y_'+corner+' FROM '+tableName + if objectNumbers is not None: + queryStatement += ' where object_id '+objectCriteria + queryStatement += ' ORDER BY object_id, frame_number' cursor.execute(queryStatement) logging.debug(queryStatement) else: @@ -361,17 +365,17 @@ return objects def loadUserTypesFromTable(cursor, trajectoryType, objectNumbers): - objectIdQuery = getTrajectoryIdQuery(objectNumbers, trajectoryType) - if objectIdQuery == '': - cursor.execute('SELECT object_id, road_user_type from objects') - else: - cursor.execute('SELECT object_id, road_user_type from objects where '+objectIdQuery[7:]) + objectCriteria = getObjectCriteria(objectNumbers) + queryStatement = 'SELECT object_id, road_user_type from objects' + if objectNumbers is not None: + queryStatement += ' where object_id '+objectCriteria + cursor.execute(queryStatement) userTypes = {} for row in cursor: userTypes[row[0]] = row[1] return userTypes -def loadTrajectoriesFromSqlite(filename, trajectoryType, objectNumbers = None): +def loadTrajectoriesFromSqlite(filename, trajectoryType, objectNumbers = None, withFeatures = False): '''Loads the first objectNumbers objects or the indices in objectNumbers from the database''' connection = sqlite3.connect(filename) @@ -390,8 +394,11 @@ cursor = connection.cursor() try: # attribute feature numbers to objects - objectIdQuery = getTrajectoryIdQuery(objectNumbers, trajectoryType) - 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 + objectCriteria = getObjectCriteria(objectNumbers) + queryStatement = 'SELECT P.trajectory_id, OF.object_id from positions P, objects_features OF where P.trajectory_id = OF.trajectory_id' + if objectNumbers is not None: + queryStatement += ' and OF.object_id '+objectCriteria + queryStatement += ' group by P.trajectory_id order by OF.object_id' # order is important to group all features per object cursor.execute(queryStatement) logging.debug(queryStatement) @@ -410,6 +417,14 @@ userTypes = loadUserTypesFromTable(cursor, trajectoryType, objectNumbers) for obj in objects: obj.userType = userTypes[obj.getNum()] + + if withFeatures: + nFeatures = 0 + for obj in objects: + nFeatures = max(nFeatures, max(obj.featureNumbers)) + features = loadTrajectoriesFromSqlite(filename, 'feature', nFeatures+1) + for obj in objects: + obj.setFeatures(features) except sqlite3.OperationalError as error: printDBError(error) @@ -512,7 +527,7 @@ connection = sqlite3.connect(filename) cursor = connection.cursor() try: - 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') + 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, IND.frame_number') interactionNum = -1 indicatorTypeNum = -1 tmpIndicators = {} @@ -521,13 +536,14 @@ interactionNum = row[0] interactions.append(events.Interaction(interactionNum, moving.TimeInterval(row[3],row[4]), row[1], row[2])) interactions[-1].indicators = {} - if indicatorTypeNum != row[5]: + if indicatorTypeNum != row[5] or row[0] != interactionNum: + indicatorTypeNum = row[5] indicatorName = events.Interaction.indicatorNames[indicatorTypeNum] indicatorValues = {row[6]:row[7]} - interactions[-1].indicators[indicatorName] = indicators.SeverityIndicator(indicatorName, indicatorValues) - indicatorTypeNum = row[5] + interactions[-1].indicators[indicatorName] = indicators.SeverityIndicator(indicatorName, indicatorValues, mostSevereIsMax = not indicatorName in events.Interaction.timeIndicators) else: indicatorValues[row[6]] = row[7] + interactions[-1].indicators[indicatorName].timeInterval.last = row[6] except sqlite3.OperationalError as error: printDBError(error) return [] @@ -656,20 +672,21 @@ if usePandas: from pandas import read_csv - from numpy import min, max, round data = read_csv(filename, delimiter=';', comment='*', header=0, skiprows = 1) generatePDLaneColumn(data) data['TIME'] = data['$VEHICLE:SIMSEC']*simulationStepsPerTimeUnit if warmUpLastInstant is not None: data = data[data['TIME']>=warmUpLastInstant] grouped = data.loc[:,['NO','TIME']].groupby(['NO'], as_index = False) - instants = grouped['TIME'].agg({'first': min, 'last': max}) + instants = grouped['TIME'].agg({'first': npmin, 'last': npmax}) for row_index, row in instants.iterrows(): objNum = int(row['NO']) tmp = data[data['NO'] == objNum] objects[objNum] = moving.MovingObject(num = objNum, timeInterval = moving.TimeInterval(row['first'], row['last'])) # positions should be rounded to nDecimals decimals only - objects[objNum].curvilinearPositions = moving.CurvilinearTrajectory(S = round(tmp['POS'].tolist(), nDecimals), Y = round(tmp['POSLAT'].tolist(), nDecimals), lanes = tmp['LANE'].tolist()) + objects[objNum].curvilinearPositions = moving.CurvilinearTrajectory(S = npround(tmp['POS'].tolist(), nDecimals), Y = npround(tmp['POSLAT'].tolist(), nDecimals), lanes = tmp['LANE'].tolist()) + if nObjects > 0 and len(objects) >= nObjects: + break return objects.values() else: inputfile = openCheck(filename, quitting = True) @@ -718,7 +735,6 @@ If lanes is not None, only the data for the selected lanes will be provided (format as string x_y where x is link index and y is lane index)''' from pandas import read_csv - from numpy import array, sum as npsum columns = ['NO', '$VEHICLE:SIMSEC', 'POS'] if lanes is not None: columns += ['LANE\LINK\NO', 'LANE\INDEX'] @@ -727,7 +743,6 @@ data.sort(['$VEHICLE:SIMSEC'], inplace = True) nStationary = 0 - from matplotlib.pyplot import plot, figure nVehicles = 0 for name, group in data.groupby(['NO'], sort = False): nVehicles += 1 @@ -754,8 +769,9 @@ nCollisions = 0 for name, group in merged.groupby(['LANE\LINK\NO', 'LANE\INDEX', 'NO_x', 'NO_y']): - diff = group['POS_x']-group['POS_y'] - if len(diff) >= 2 and min(diff) < 0 and max(diff) > 0: + diff = group['POS_x'].convert_objects(convert_numeric=True)-group['POS_y'].convert_objects(convert_numeric=True) + # diff = group['POS_x']-group['POS_y'] # to check the impact of convert_objects and the possibility of using type conversion in read_csv or function to convert strings if any + if len(diff) >= 2 and npmin(diff) < 0 and npmax(diff) > 0: xidx = diff[diff < 0].argmax() yidx = diff[diff > 0].argmin() if abs(group.loc[xidx, '$VEHICLE:SIMSEC'] - group.loc[yidx, '$VEHICLE:SIMSEC']) <= collisionTimeDifference: @@ -874,7 +890,6 @@ def loadConfigFile(self, filename): from ConfigParser import ConfigParser - from numpy import loadtxt from os import path config = ConfigParser() @@ -901,7 +916,21 @@ self.videoFrameRate = config.getfloat(self.sectionHeader, 'video-fps') # Classification parameters - + self.speedAggregationMethod = config.get(self.sectionHeader, 'speed-aggregation-method') + self.nFramesIgnoreAtEnds = config.getint(self.sectionHeader, 'nframes-ignore-at-ends') + self.speedAggregationQuantile = config.getint(self.sectionHeader, 'speed-aggregation-quantile') + self.minSpeedEquiprobable = config.getfloat(self.sectionHeader, 'min-speed-equiprobable') + self.minNPixels = config.getint(self.sectionHeader, 'min-npixels-crop') + self.pedBikeCarSVMFilename = config.get(self.sectionHeader, 'pbv-svm-filename') + self.bikeCarSVMFilename = config.get(self.sectionHeader, 'bv-svm-filename') + self.maxPedestrianSpeed = config.getfloat(self.sectionHeader, 'max-ped-speed') + self.maxCyclistSpeed = config.getfloat(self.sectionHeader, 'max-cyc-speed') + self.meanPedestrianSpeed = config.getfloat(self.sectionHeader, 'mean-ped-speed') + self.stdPedestrianSpeed = config.getfloat(self.sectionHeader, 'std-ped-speed') + self.locationCyclistSpeed = config.getfloat(self.sectionHeader, 'cyc-speed-loc') + self.scaleCyclistSpeed = config.getfloat(self.sectionHeader, 'cyc-speed-scale') + self.meanVehicleSpeed = config.getfloat(self.sectionHeader, 'mean-veh-speed') + self.stdVehicleSpeed = config.getfloat(self.sectionHeader, 'std-veh-speed') # Safety parameters self.maxPredictedSpeed = config.getfloat(self.sectionHeader, 'max-predicted-speed')/3.6/self.videoFrameRate @@ -921,6 +950,26 @@ if filename is not None: self.loadConfigFile(filename) + def convertToFrames(self, speedRatio = 3.6): + '''Converts parameters with a relationship to time in 'native' frame time + speedRatio is the conversion from the speed unit in the config file + to the distance per second + + ie param(config file) = speedRatio x fps x param(used in program) + eg km/h = 3.6 (m/s to km/h) x frame/s x m/frame''' + denominator = self.videoFrameRate*speedRatio + denominator2 = denominator**2 + self.minSpeedEquiprobable = self.minSpeedEquiprobable/denominator + self.maxPedestrianSpeed = self.maxPedestrianSpeed/denominator + self.maxCyclistSpeed = self.maxCyclistSpeed/denominator + self.meanPedestrianSpeed = self.meanPedestrianSpeed/denominator + self.stdPedestrianSpeed = self.stdPedestrianSpeed/denominator + self.meanVehicleSpeed = self.meanVehicleSpeed/denominator + self.stdVehicleSpeed = self.stdVehicleSpeed/denominator + # special case for the lognormal distribution + self.locationCyclistSpeed = self.locationCyclistSpeed-log(denominator) + #self.scaleCyclistSpeed = self.scaleCyclistSpeed + class SceneParameters(object): def __init__(self, config, sectionName): from ConfigParser import NoOptionError