changeset 378:3805b9639647

added tests for movement orientation, object size
author Nicolas Saunier <nicolas.saunier@polymtl.ca>
date Thu, 18 Jul 2013 21:55:17 -0400
parents 2aed569f39e7
children f1a1923ddff9
files python/events.py python/moving.py
diffstat 2 files changed, 60 insertions(+), 12 deletions(-) [+]
line wrap: on
line diff
--- a/python/events.py	Thu Jul 18 02:08:51 2013 -0400
+++ b/python/events.py	Thu Jul 18 21:55:17 2013 -0400
@@ -96,14 +96,10 @@
         # todo test for interaction instants and interval, compute indicators
 
         # if we have features, compute other indicators
-        if self.roadUser1.features and self.roadUser2.features:
-            from scipy.spatial.distance import cdist
+        if self.roadUser1.features != None and self.roadUser2.features != None:
             minDistance={}
             for instant in self.timeInterval:
-                positions1 = [f.getPositionAtInstant(instant).astuple() for f in self.roadUser1.features if f.existsAtInstant(instant)]
-                positions2 = [f.getPositionAtInstant(instant).astuple() for f in self.roadUser2.features if f.existsAtInstant(instant)]
-                distance = cdist(positions1, positions2, metric = 'euclidean')
-                minDistance[instant] = distance.min()
+                minDistance[instant] = MovingObject.minDistance(self.roadUser1, self.roadUser2, instant)
             self.addIndicator(indicators.SeverityIndicator('Minimum Distance', minDistance))
 
     def computeCrossingsCollisions(self, predictionParameters, collisionDistanceThreshold, timeHorizon, computeCZ = False, debug = False, timeInterval = None):
--- a/python/moving.py	Thu Jul 18 02:08:51 2013 -0400
+++ b/python/moving.py	Thu Jul 18 21:55:17 2013 -0400
@@ -247,6 +247,10 @@
         return p1.x*p2.y-p1.y*p2.x
 
     @staticmethod
+    def cosine(p1, p2):
+        return Point.dot(p1,p2)/(p1.norm2()*p2.norm2())
+
+    @staticmethod
     def distanceNorm2(p1, p2):
         return (p1-p2).norm2()
 
@@ -255,6 +259,10 @@
         from matplotlib.pyplot import scatter
         scatter([p.x for p in points],[p.y for p in points], **kwargs)
 
+    def similarOrientation(self, refDirection, cosineThreshold):
+        'Indicates whether the cosine of the vector and refDirection is smaller than cosineThreshold'
+        return Point.cosine(self, refDirection) >= cosineThreshold
+
 if shapelyAvailable:
     def pointsInPolygon(points, polygon):
         '''Optimized tests of a series of points within (Shapely) polygon '''
@@ -512,6 +520,19 @@
             displacement += Point.distanceNorm2(self.__getitem__(i),self.__getitem__(i+1))
         return displacement
 
+    def similarOrientation(self, refDirection, cosineThreshold):
+        '''Indicates whether the majority of the trajectory elements (vectors for velocity) 
+        have a cosine with refDirection is smaller than cosineThreshold'''
+        count = 0
+        halfLength = float(self.length())/2
+        for p in self:
+            if p.similarOrientation(refDirection, cosineThreshold):
+                count += 1
+            if count > halfLength:
+                return True
+        return False
+
+
     def wiggliness(self):
         return self.cumulatedDisplacement()/float(Point.distanceNorm2(self.__getitem__(0),self.__getitem__(self.length()-1)))
 
@@ -687,11 +708,12 @@
     def play(self, videoFilename, homography = None):
         cvutils.displayTrajectories(videoFilename, [self], homography, self.getFirstInstant(), self.getLastInstant())
 
-    def speedDiagnostics(self, display = False):
+    def speedDiagnostics(self, framerate = 1., display = False):
         from numpy import std
-        speeds = self.getSpeeds()
+        from scipy.stats import scoreatpercentile
+        speeds = framerate*self.getSpeeds()
         coef = utils.linearRegression(range(len(speeds)), speeds)
-        print(speeds[-2]-speeds[1], std(speeds), coef[0])
+        print(min(speeds), scoreatpercentile(speeds, 5), speeds[-2]-speeds[1], std(speeds), coef[0])
         if display:
             from matplotlib.pyplot import figure, plot
             figure(1)
@@ -699,6 +721,37 @@
             figure(2)
             plot(list(self.getTimeInterval()), speeds)
 
+    @staticmethod
+    def distances(obj1, obj2, instant):
+        from scipy.spatial.distance import cdist
+        positions1 = [f.getPositionAtInstant(instant).astuple() for f in obj1.features if f.existsAtInstant(instant)]
+        positions2 = [f.getPositionAtInstant(instant).astuple() for f in obj2.features if f.existsAtInstant(instant)]
+        return cdist(positions1, positions2, metric = 'euclidean')
+        
+    @staticmethod
+    def minDistance(obj1, obj2, instant):
+        return MovingObject.distances(obj1, obj2, instant).min()
+
+    @staticmethod
+    def maxDistance(obj1, obj2, instant):
+        return MovingObject.distances(obj1, obj2, instant).max()
+
+    def maxSize(self):
+        '''Returns the max distance between features
+        at instant there are the most features'''
+        if hasattr(self, 'features'):
+            nFeatures = -1
+            tMaxFeatures = 0
+            for t in self.getTimeInterval():
+                n = len([f for f in self.features if f.existsAtInstant(t)])
+                if n > nFeatures:
+                    nFeatures = n
+                    tMaxFeatures = t
+            return MovingObject.maxDistance(self, self, tMaxFeatures)
+        else:
+            print('Load features to compute a maximum size')
+            return None
+            
     def getInstantsCrossingLane(self, p1, p2):
         '''Returns the instant(s)
         at which the object passes from one side of the segment to the other
@@ -730,9 +783,8 @@
     @staticmethod
     def collisionCourseCosine(movingObject1, movingObject2, instant):
         'A positive result indicates that the road users are getting closer'
-        deltap = movingObject1.getPositionAtInstant(instant)-movingObject2.getPositionAtInstant(instant)
-        deltav = movingObject2.getVelocityAtInstant(instant)-movingObject1.getVelocityAtInstant(instant)
-        return Point.dot(deltap, deltav)/(deltap.norm2()*deltav.norm2())
+        return Point.cosine(movingObject1.getPositionAtInstant(instant)-movingObject2.getPositionAtInstant(instant), #deltap
+                            movingObject2.getVelocityAtInstant(instant)-movingObject1.getVelocityAtInstant(instant)) #deltav
 
 def plotRoadUsers(objects, colors):
     '''Colors is a PlottingPropertyValues instance'''