changeset 661:dc70d9e711f5

some method name change and new methods for features in objects (MovingObject) and methods to access indicator values in interactions
author Nicolas Saunier <nicolas.saunier@polymtl.ca>
date Mon, 18 May 2015 13:53:25 +0200
parents 994dd644f6ab
children 72174e66aba5
files python/cvutils.py python/events.py python/indicators.py python/moving.py python/objectsmoothing.py python/prediction.py python/tests/moving.txt
diffstat 7 files changed, 103 insertions(+), 44 deletions(-) [+]
line wrap: on
line diff
--- a/python/cvutils.py	Fri May 15 23:09:49 2015 +0200
+++ b/python/cvutils.py	Mon May 18 13:53:25 2015 +0200
@@ -238,11 +238,12 @@
         'Computes the bounding box of object at frameNum'
         x = []
         y = []
-        for f in obj.features:
-            if f.existsAtInstant(frameNum):
-                projectedPosition = f.getPositionAtInstant(frameNum).project(homography)
-                x.append(projectedPosition.x)
-                y.append(projectedPosition.y)
+        if obj.hasFeatures():
+            for f in obj.getFeatures():
+                if f.existsAtInstant(frameNum):
+                    projectedPosition = f.getPositionAtInstant(frameNum).project(homography)
+                    x.append(projectedPosition.x)
+                    y.append(projectedPosition.y)
         xmin = min(x)
         xmax = max(x)
         ymin = min(y)
@@ -304,7 +305,7 @@
                             if frameNum in boundingBoxes.keys():
                                 for rect in boundingBoxes[frameNum]:
                                     cv2.rectangle(img, rect[0].asint().astuple(), rect[1].asint().astuple(), cvRed)
-                            elif len(obj.features) != 0:
+                            elif obj.hasFeatures():
                                 imgcrop, yCropMin, yCropMax, xCropMin, xCropMax = imageBox(img, obj, frameNum, homography, width, height)
                                 cv2.rectangle(img, (xCropMin, yCropMin), (xCropMax, yCropMax), cvBlue, 1)
                             objDescription = '{} '.format(obj.num)
--- a/python/events.py	Fri May 15 23:09:49 2015 +0200
+++ b/python/events.py	Mon May 18 13:53:25 2015 +0200
@@ -104,6 +104,7 @@
         self.categoryNum = categoryNum
         self.indicators = {}
         self.interactionInterval = None
+        self.collisionPoints = None # distionary for collison points with different prediction methods
 
     def getRoadUserNumbers(self):
         return self.roadUserNumbers
@@ -128,9 +129,24 @@
         return self.indicators.get(indicatorName, None)
 
     def addIndicator(self, indicator):
-        if indicator:
+        if indicator is not None:
             self.indicators[indicator.name] = indicator
 
+    def getIndicatorValueAtInstant(self, indicatorName, instant):
+        indicator = self.getIndicator(indicatorName)
+        if indicator is not None:
+            return indicator[instant]
+        else:
+            return None
+
+    def getIndicatorValuesAtInstant(self, instant):
+        '''Returns list of indicator values at instant
+        as dict (with keys from indicators dict)'''
+        values = {}
+        for k, indicator in self.indicators.iteritems():
+            values[k] = indicator[instant]
+        return values
+        
     def plot(self, options = '', withOrigin = False, timeStep = 1, withFeatures = False, **kwargs):
         self.roadUser1.plot(options, withOrigin, timeStep, withFeatures, **kwargs)
         self.roadUser2.plot(options, withOrigin, timeStep, withFeatures, **kwargs)
@@ -177,7 +193,7 @@
         self.addIndicator(indicators.SeverityIndicator(Interaction.indicatorNames[5], speedDifferentials))
 
         # if we have features, compute other indicators
-        if len(self.roadUser1.features) != 0 and len(self.roadUser2.features) != 0:
+        if self.roadUser1.hasFeatures() and self.roadUser2.hasFeatures():
             minDistance={}
             for instant in self.timeInterval:
                 minDistance[instant] = moving.MovingObject.minDistance(self.roadUser1, self.roadUser2, instant)
@@ -196,7 +212,9 @@
             commonTimeInterval = timeInterval
         else:
             commonTimeInterval = self.timeInterval
-        self.collisionPoints, self.crossingZones = predictionParameters.computeCrossingsCollisions(self.roadUser1, self.roadUser2, collisionDistanceThreshold, timeHorizon, computeCZ, debug, commonTimeInterval, nProcesses,usePrototypes,route1,route2,prototypes,secondStepPrototypes,nMatching,objects,noiseEntryNums,noiseExitNums,minSimilarity,mostMatched,useDestination,useSpeedPrototype,acceptPartialLength, step)
+        self.collisionPoints[predictionParameters.name], crossingZones = predictionParameters.computeCrossingsCollisions(self.roadUser1, self.roadUser2, collisionDistanceThreshold, timeHorizon, computeCZ, debug, commonTimeInterval, nProcesses,usePrototypes,route1,route2,prototypes,secondStepPrototypes,nMatching,objects,noiseEntryNums,noiseExitNums,minSimilarity,mostMatched,useDestination,useSpeedPrototype,acceptPartialLength, step)
+        if computeCZ:
+            self.crossingZones[predictionParameters.name] = crossingZones
         for i, cp in self.collisionPoints.iteritems():
             TTCs[i] = prediction.SafetyPoint.computeExpectedIndicator(cp)
         # add probability of collision, and probability of successful evasive action
@@ -213,11 +231,24 @@
         self.pet = moving.MovingObject.computePET(self.roadUser1, self.roadUser2, collisionDistanceThreshold)
 
     def addVideoFilename(self,videoFilename):
-        self.videoFilename= videoFilename
+        self.videoFilename = videoFilename
 
     def addInteractionType(self,interactionType):
         ''' interaction types: conflict or collision if they are known'''
-        self.interactionType= interactionType
+        self.interactionType = interactionType
+
+    def getCrossingZones(self, predictionMethodName):
+        if self.hasattr(self, 'crossingZones'):
+            return self.crossingZones[predictionMethodName]
+        else:
+            return None
+
+    def getCollisionPoints(self, predictionMethodName):
+        if self.collisionPoints is not None:
+            return self.collisionPoints[predictionMethodName]
+        else:
+            return None
+
 
 def createInteractions(objects, _others = None):
     '''Create all interactions of two co-existing road users'''
--- a/python/indicators.py	Fri May 15 23:09:49 2015 +0200
+++ b/python/indicators.py	Mon May 18 13:53:25 2015 +0200
@@ -39,10 +39,10 @@
     def empty(self):
         return len(self.values) == 0
 
-    def __getitem__(self, i):
-        'Returns ith value in time interval'
-        if i in self.values.keys():
-            return self.values[i]
+    def __getitem__(self, t):
+        'Returns the value at time t'
+        if t in self.values.keys():
+            return self.values[t]
         else:
             return None
 
--- a/python/moving.py	Fri May 15 23:09:49 2015 +0200
+++ b/python/moving.py	Mon May 18 13:53:25 2015 +0200
@@ -986,7 +986,7 @@
         self.velocities = velocities
         self.geometry = geometry
         self.userType = userType
-        self.features = []
+        self.features = None
         # compute bounding polygon from trajectory
         
     @staticmethod
@@ -1105,6 +1105,18 @@
     def setFeatures(self, features):
         self.features = [features[i] for i in self.featureNumbers]
 
+    def getFeatures(self):
+        return self.features
+
+    def hasFeatures(self):
+        return (self.features is not None)
+
+    def getFeature(self, i):
+        if self.hasFeatures() and i<len(self.features):
+            return self.features[i]
+        else:
+            return None
+
     def getSpeeds(self):
         return self.getVelocities().norm()
 
@@ -1131,8 +1143,8 @@
         return self.positions.getYCoordinates()
     
     def plot(self, options = '', withOrigin = False, timeStep = 1, withFeatures = False, **kwargs):
-        if withFeatures:
-            for f in self.features:
+        if withFeatures and self.hasFeatures():
+            for f in self.getFeatures():
                 f.positions.plot('r', True, timeStep, **kwargs)
             self.positions.plot('bx-', True, timeStep, **kwargs)
         else:
--- a/python/objectsmoothing.py	Fri May 15 23:09:49 2015 +0200
+++ b/python/objectsmoothing.py	Mon May 18 13:53:25 2015 +0200
@@ -14,14 +14,14 @@
     return min(dist, key=dist.get) # = utils.argmaxDict(dist)
     
 def getFeatures(obj, featureID):
-    first = obj.features[featureID].getFirstInstant()
-    last = obj.features[featureID].getLastInstant()
-    featureList=[[obj.features[featureID],first,last,moving.Point(0,0)]]
+    currentFeature = obj.getFeature(featureID)
+    first = currentFeature.getFirstInstant()
+    last = currentFeature.getLastInstant()
+    featureList=[[currentFeature,first,last,moving.Point(0,0)]]
     # find the features to fill in the beginning of the object existence
-    currentFeature = obj.features[featureID]
     while first != obj.getFirstInstant():
         delta=featureList[-1][3]
-        featureSet = [f for f in obj.features if f.existsAtInstant(first-1)]
+        featureSet = [f for f in obj.getFeatures() if f.existsAtInstant(first-1)]
         feat = findNearest(currentFeature,featureSet,first-1,reverse=True)
         if feat.existsAtInstant(first):
             featureList.append([feat,feat.getFirstInstant(),first-1,(currentFeature.getPositionAtInstant(first)-feat.getPositionAtInstant(first))+delta])
@@ -31,9 +31,9 @@
         first= feat.getFirstInstant()
     # find the features to fill in the end of the object existence
     delta=moving.Point(0,0)
-    currentFeature = obj.features[featureID]
+    currentFeature = obj.getFeature(featureID) # need to reinitialize
     while last!= obj.getLastInstant():
-        featureSet = [f for f in obj.features if f.existsAtInstant(last+1)]
+        featureSet = [f for f in obj.getFeatures() if f.existsAtInstant(last+1)]
         feat = findNearest(currentFeature,featureSet,last+1,reverse=False)
         if feat.existsAtInstant(last):
             featureList.append([feat,last+1,feat.getLastInstant(),(currentFeature.getPositionAtInstant(last)-feat.getPositionAtInstant(last))+delta])
@@ -120,7 +120,7 @@
     if create:
         feature = buildFeature(obj, featureID , num=1) # why num=1
     else:
-        feature = obj.features[featureID]
+        feature = obj.getFeature(featureID)
     for t in feature.getTimeInterval():
         p1= feature.getPositionAtInstant(t)
         p2= obj.getPositionAtInstant(t)
@@ -180,14 +180,14 @@
     
     The object should have its features in obj.features
     TODO: check whether features are necessary'''
-    if len(obj.features) == 0:
+    if not obj.hasFeatures():
         print('Object {} has an empty list of features: please load and add them using obj.setFeatures(features)'.format(obj.getNum()))
         from sys import exit
         exit()
 
-    featureList=[i for i,f in enumerate(obj.features) if f.length() >= minLengthParam*obj.length()]
+    featureList=[i for i,f in enumerate(obj.getFeatures()) if f.length() >= minLengthParam*obj.length()]
     if featureList==[]:
-        featureList.append(utils.argmaxDict({i:f.length() for i,f in enumerate(obj.features)}))
+        featureList.append(utils.argmaxDict({i:f.length() for i,f in enumerate(obj.getFeatures())}))
         create = True
     newObjects = []
     for featureID in featureList: # featureID should be the index in the list of obj.features
@@ -232,14 +232,14 @@
                 newObj.velocities= obj.velocities
 
     newObj.featureNumbers=obj.featureNumbers
-    newObj.features=obj.features
+    newObj.features=obj.getFeatures()
     newObj.userType=obj.userType
 
     if plotResults:
         plt.figure()
         plt.title('objects_id = {}'.format(obj.num))
         for i in featureList:
-            obj.features[i].plot('cx-')
+            obj.getFeature(i).plot('cx-')
         obj.plot('rx-')
         newObj.plot('gx-')        
     return newObj
--- a/python/prediction.py	Fri May 15 23:09:49 2015 +0200
+++ b/python/prediction.py	Mon May 18 13:53:25 2015 +0200
@@ -410,8 +410,8 @@
 
     def generatePredictedTrajectories(self, obj, instant):
         predictedTrajectories = []
-        if self.useFeatures:
-            features = [f for f in obj.features if f.existsAtInstant(instant)]
+        if self.useFeatures and obj.hadFeatures():
+            features = [f for f in obj.getFeatures() if f.existsAtInstant(instant)]
             positions = [f.getPositionAtInstant(instant) for f in features]
             velocities = [f.getVelocityAtInstant(instant) for f in features]
         else:
@@ -433,15 +433,19 @@
         #self.nPredictedTrajectories = nPredictedTrajectories
     
     def generatePredictedTrajectories(self, obj, instant):
-        predictedTrajectories = []        
-        features = [f for f in obj.features if f.existsAtInstant(instant)]
-        positions = [f.getPositionAtInstant(instant) for f in features]
-        velocities = [f.getVelocityAtInstant(instant) for f in features]
-        #for i in xrange(self.nPredictedTrajectories):
-        for initialPosition,initialVelocity in zip(positions, velocities):
-            predictedTrajectories.append(PredictedTrajectoryConstant(initialPosition, initialVelocity, 
-                                                                     maxSpeed = self.maxSpeed))
-        return predictedTrajectories
+        predictedTrajectories = []
+        if obj.hasFeatures():
+            features = [f for f in obj.getFeatures() if f.existsAtInstant(instant)]
+            positions = [f.getPositionAtInstant(instant) for f in features]
+            velocities = [f.getVelocityAtInstant(instant) for f in features]
+            #for i in xrange(self.nPredictedTrajectories):
+            for initialPosition,initialVelocity in zip(positions, velocities):
+                predictedTrajectories.append(PredictedTrajectoryConstant(initialPosition, initialVelocity, 
+                                                                         maxSpeed = self.maxSpeed))
+            return predictedTrajectories
+        else:
+            print('Object {} has no features'.format(obj.getNum()))
+            return None
 
 class EvasiveActionPredictionParameters(PredictionParameters):
     def __init__(self, maxSpeed, nPredictedTrajectories, accelerationDistribution, steeringDistribution, useFeatures = False):
@@ -463,8 +467,8 @@
 
     def generatePredictedTrajectories(self, obj, instant):
         predictedTrajectories = []
-        if self.useFeatures:
-            features = [f for f in obj.features if f.existsAtInstant(instant)]
+        if self.useFeatures and obj.hasFeatures():
+            features = [f for f in obj.getFeatures() if f.existsAtInstant(instant)]
             positions = [f.getPositionAtInstant(instant) for f in features]
             velocities = [f.getVelocityAtInstant(instant) for f in features]
         else:
--- a/python/tests/moving.txt	Fri May 15 23:09:49 2015 +0200
+++ b/python/tests/moving.txt	Mon May 18 13:53:25 2015 +0200
@@ -1,4 +1,5 @@
 >>> from moving import *
+>>> import storage
 >>> import numpy as np
 
 >>> Interval().empty()
@@ -137,6 +138,16 @@
 >>> Point.midPoint(p1, p2)
 (0.500000,0.500000)
 
+>>> objects = storage.loadTrajectoriesFromSqlite('../samples/laurier.sqlite', 'object')
+>>> len(objects)
+5
+>>> objects[0].hasFeatures()
+False
+>>> features = storage.loadTrajectoriesFromSqlite('../samples/laurier.sqlite', 'feature')
+>>> for o in objects: o.setFeatures(features)
+>>> objects[0].hasFeatures()
+True
+
 >>> o1 = MovingObject.generate(Point(-5.,0.), Point(1.,0.), TimeInterval(0,10))
 >>> o2 = MovingObject.generate(Point(0.,-5.), Point(0.,1.), TimeInterval(0,10))
 >>> MovingObject.computePET(o1, o2, 0.1)