diff python/storage.py @ 509:935430b1d408

corrected mask bug in feature tracking, updated display-trajectories to display on undistorted image
author Nicolas Saunier <nicolas.saunier@polymtl.ca>
date Fri, 23 May 2014 16:27:26 -0400
parents 343cfd185ca6
children 1ba618fb0f70
line wrap: on
line diff
--- a/python/storage.py	Fri May 23 10:35:51 2014 -0400
+++ b/python/storage.py	Fri May 23 16:27:26 2014 -0400
@@ -9,6 +9,10 @@
 __metaclass__ = type
 
 
+commentChar = '#'
+
+delimiterChar = '%';
+
 ngsimUserTypes = {'twowheels':1,
                   'car':2,
                   'truck':3}
@@ -352,6 +356,69 @@
 # txt files
 #########################
 
+def openCheck(filename, option = 'r', quit = False):
+    '''Open file filename in read mode by default
+    and checks it is open'''
+    try:
+        return open(filename, option)
+    except IOError:
+        print 'File %s could not be opened.' % filename
+        if quit:
+            from sys import exit
+            exit()
+        return None
+
+def readline(f, commentChar = commentChar):
+    '''Modified readline function to skip comments.'''
+    s = f.readline()
+    while (len(s) > 0) and s.startswith(commentChar):
+        s = f.readline()
+    return s.strip()
+
+def getLines(f, commentChar = commentChar):
+    '''Gets a complete entry (all the lines) in between delimiterChar.'''
+    dataStrings = []
+    s = readline(f, commentChar)
+    while len(s) > 0:
+        dataStrings += [s.strip()]
+        s = readline(f, commentChar)
+    return dataStrings
+
+def writeList(filename, l):
+    f = utils.openCheck(filename, 'w')
+    for x in l:
+        f.write('{}\n'.format(x))
+    f.close()
+
+def loadListStrings(filename, commentChar = commentChar):
+    f = utils.openCheck(filename, 'r')
+    result = getLines(f, commentChar)
+    f.close()
+    return result
+
+def getValuesFromINIFile(filename, option, delimiterChar = '=', commentChar = commentChar):
+    values = []
+    for l in loadListStrings(filename, commentChar):
+        if l.startswith(option):
+            values.append(l.split(delimiterChar)[1].strip())
+    return values
+
+class FakeSecHead(object):
+    '''Add fake section header [asection]
+
+    from http://stackoverflow.com/questions/2819696/parsing-properties-file-in-python/2819788#2819788
+    use read_file in Python 3.2+
+    '''
+    def __init__(self, fp):
+        self.fp = fp
+        self.sechead = '[main]\n'
+
+    def readline(self):
+        if self.sechead:
+            try: return self.sechead
+            finally: self.sechead = None
+        else: return self.fp.readline()
+
 def loadTrajectoriesFromNgsimFile(filename, nObjects = -1, sequenceNum = -1):
     '''Reads data from the trajectory data provided by NGSIM project 
     and returns the list of Feature objects'''
@@ -454,18 +521,89 @@
         writePositionsToCsv(f, obj)
     f.close()
 
-def writeList(filename, l):
-    f = utils.openCheck(filename, 'w')
-    for x in l:
-        f.write('{}\n'.format(x))
-    f.close()
+
+#########################
+# Utils to read .ini type text files for configuration, meta data...
+#########################
+
+class TrackingParameters:
+    '''Class for tracking and safety parameters
+
+    Note: framerate is already taken into account'''
+
+    def loadConfigFile(self, filename):
+        from ConfigParser import ConfigParser
+        from numpy import loadtxt
+        from os import path
+
+        config = ConfigParser()
+        config.readfp(FakeSecHead(openCheck(filename)))
+        self.sectionHeader = config.sections()[0]
+        self.videoFilename = config.get(self.sectionHeader, 'video-filename')
+        self.databaseFilename = config.get(self.sectionHeader, 'database-filename')
+        self.homographyFilename = config.get(self.sectionHeader, 'homography-filename')
+        if (path.exists(self.homographyFilename)):
+            self.homography = loadtxt(self.homographyFilename)
+        else:
+            self.homography = None
+        self.intrinsicCameraFilename = config.get(self.sectionHeader, 'intrinsic-camera-filename')
+        if (path.exists(self.intrinsicCameraFilename)):
+            self.intrinsicCameraMatrix = loadtxt(self.intrinsicCameraFilename)
+        else:
+            self.intrinsicCameraMatrix = None
+        distortionCoefficients = getValuesFromINIFile(filename, 'distortion-coefficients', '=')        
+        self.distortionCoefficients = [float(x) for x in distortionCoefficients]
+        self.undistortedImageMultiplication  = config.getfloat(self.sectionHeader, 'undistorted-size-multiplication')
+        self.undistort = config.getboolean(self.sectionHeader, 'undistort')
+        self.firstFrameNum = config.getint(self.sectionHeader, 'frame1')
+        self.videoFrameRate = config.getfloat(self.sectionHeader, 'video-fps')
 
-def loadListStrings(filename):
-    f = utils.openCheck(filename, 'r')
-    result = [l.strip() for l in f]
-    f.close()
-    return result
-        
+        self.maxPredictedSpeed = config.getfloat(self.sectionHeader, 'max-predicted-speed')/3.6/self.videoFrameRate
+        self.predictionTimeHorizon = config.getfloat(self.sectionHeader, 'prediction-time-horizon')*self.videoFrameRate
+        self.collisionDistance = config.getfloat(self.sectionHeader, 'collision-distance')
+        self.crossingZones = config.getboolean(self.sectionHeader, 'crossing-zones')
+        self.predictionMethod = config.get(self.sectionHeader, 'prediction-method')
+        self.nPredictedTrajectories = config.getint(self.sectionHeader, 'npredicted-trajectories')
+        self.maxNormalAcceleration = config.getfloat(self.sectionHeader, 'max-normal-acceleration')/self.videoFrameRate**2
+        self.maxNormalSteering = config.getfloat(self.sectionHeader, 'max-normal-steering')/self.videoFrameRate
+        self.minExtremeAcceleration = config.getfloat(self.sectionHeader, 'min-extreme-acceleration')/self.videoFrameRate**2
+        self.maxExtremeAcceleration = config.getfloat(self.sectionHeader, 'max-extreme-acceleration')/self.videoFrameRate**2
+        self.maxExtremeSteering = config.getfloat(self.sectionHeader, 'max-extreme-steering')/self.videoFrameRate
+        self.useFeaturesForPrediction = config.getboolean(self.sectionHeader, 'use-features-prediction')
+
+    def __init__(self, filename = None):
+        if filename != None:
+            self.loadConfigFile(filename)
+
+class SceneParameters:
+    def __init__(self, config, sectionName):
+        from ConfigParser import NoOptionError
+        from ast import literal_eval
+        try:
+            self.sitename = config.get(sectionName, 'sitename')
+            self.databaseFilename = config.get(sectionName, 'data-filename')
+            self.homographyFilename = config.get(sectionName, 'homography-filename')
+            self.calibrationFilename = config.get(sectionName, 'calibration-filename') 
+            self.videoFilename = config.get(sectionName, 'video-filename')
+            self.frameRate = config.getfloat(sectionName, 'framerate')
+            self.date = datetime.strptime(config.get(sectionName, 'date'), datetimeFormat) # 2011-06-22 11:00:39
+            self.translation = literal_eval(config.get(sectionName, 'translation')) #         = [0.0, 0.0]
+            self.rotation = config.getfloat(sectionName, 'rotation')
+            self.duration = config.getint(sectionName, 'duration')
+        except NoOptionError as e:
+            print(e)
+            print('Not a section for scene meta-data')
+
+    @staticmethod
+    def loadConfigFile(filename):
+        from ConfigParser import ConfigParser
+        config = ConfigParser()
+        config.readfp(openCheck(filename))
+        configDict = dict()
+        for sectionName in config.sections():
+            configDict[sectionName] = SceneParameters(config, sectionName) 
+        return configDict
+
 
 if __name__ == "__main__":
     import doctest