comparison python/moving.py @ 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
comparison
equal deleted inserted replaced
377:2aed569f39e7 378:3805b9639647
245 def cross(p1, p2): 245 def cross(p1, p2):
246 'Cross product' 246 'Cross product'
247 return p1.x*p2.y-p1.y*p2.x 247 return p1.x*p2.y-p1.y*p2.x
248 248
249 @staticmethod 249 @staticmethod
250 def cosine(p1, p2):
251 return Point.dot(p1,p2)/(p1.norm2()*p2.norm2())
252
253 @staticmethod
250 def distanceNorm2(p1, p2): 254 def distanceNorm2(p1, p2):
251 return (p1-p2).norm2() 255 return (p1-p2).norm2()
252 256
253 @staticmethod 257 @staticmethod
254 def plotAll(points, **kwargs): 258 def plotAll(points, **kwargs):
255 from matplotlib.pyplot import scatter 259 from matplotlib.pyplot import scatter
256 scatter([p.x for p in points],[p.y for p in points], **kwargs) 260 scatter([p.x for p in points],[p.y for p in points], **kwargs)
261
262 def similarOrientation(self, refDirection, cosineThreshold):
263 'Indicates whether the cosine of the vector and refDirection is smaller than cosineThreshold'
264 return Point.cosine(self, refDirection) >= cosineThreshold
257 265
258 if shapelyAvailable: 266 if shapelyAvailable:
259 def pointsInPolygon(points, polygon): 267 def pointsInPolygon(points, polygon):
260 '''Optimized tests of a series of points within (Shapely) polygon ''' 268 '''Optimized tests of a series of points within (Shapely) polygon '''
261 prepared_polygon = prep(polygon) 269 prepared_polygon = prep(polygon)
509 'Returns the sum of the distances between each successive point' 517 'Returns the sum of the distances between each successive point'
510 displacement = 0 518 displacement = 0
511 for i in xrange(self.length()-1): 519 for i in xrange(self.length()-1):
512 displacement += Point.distanceNorm2(self.__getitem__(i),self.__getitem__(i+1)) 520 displacement += Point.distanceNorm2(self.__getitem__(i),self.__getitem__(i+1))
513 return displacement 521 return displacement
522
523 def similarOrientation(self, refDirection, cosineThreshold):
524 '''Indicates whether the majority of the trajectory elements (vectors for velocity)
525 have a cosine with refDirection is smaller than cosineThreshold'''
526 count = 0
527 halfLength = float(self.length())/2
528 for p in self:
529 if p.similarOrientation(refDirection, cosineThreshold):
530 count += 1
531 if count > halfLength:
532 return True
533 return False
534
514 535
515 def wiggliness(self): 536 def wiggliness(self):
516 return self.cumulatedDisplacement()/float(Point.distanceNorm2(self.__getitem__(0),self.__getitem__(self.length()-1))) 537 return self.cumulatedDisplacement()/float(Point.distanceNorm2(self.__getitem__(0),self.__getitem__(self.length()-1)))
517 538
518 def getIntersections(self, p1, p2): 539 def getIntersections(self, p1, p2):
685 self.positions.drawOnWorldImage(nPixelsPerUnitDistance, imageHeight, options, withOrigin, timeStep, **kwargs) 706 self.positions.drawOnWorldImage(nPixelsPerUnitDistance, imageHeight, options, withOrigin, timeStep, **kwargs)
686 707
687 def play(self, videoFilename, homography = None): 708 def play(self, videoFilename, homography = None):
688 cvutils.displayTrajectories(videoFilename, [self], homography, self.getFirstInstant(), self.getLastInstant()) 709 cvutils.displayTrajectories(videoFilename, [self], homography, self.getFirstInstant(), self.getLastInstant())
689 710
690 def speedDiagnostics(self, display = False): 711 def speedDiagnostics(self, framerate = 1., display = False):
691 from numpy import std 712 from numpy import std
692 speeds = self.getSpeeds() 713 from scipy.stats import scoreatpercentile
714 speeds = framerate*self.getSpeeds()
693 coef = utils.linearRegression(range(len(speeds)), speeds) 715 coef = utils.linearRegression(range(len(speeds)), speeds)
694 print(speeds[-2]-speeds[1], std(speeds), coef[0]) 716 print(min(speeds), scoreatpercentile(speeds, 5), speeds[-2]-speeds[1], std(speeds), coef[0])
695 if display: 717 if display:
696 from matplotlib.pyplot import figure, plot 718 from matplotlib.pyplot import figure, plot
697 figure(1) 719 figure(1)
698 self.draw() 720 self.draw()
699 figure(2) 721 figure(2)
700 plot(list(self.getTimeInterval()), speeds) 722 plot(list(self.getTimeInterval()), speeds)
701 723
724 @staticmethod
725 def distances(obj1, obj2, instant):
726 from scipy.spatial.distance import cdist
727 positions1 = [f.getPositionAtInstant(instant).astuple() for f in obj1.features if f.existsAtInstant(instant)]
728 positions2 = [f.getPositionAtInstant(instant).astuple() for f in obj2.features if f.existsAtInstant(instant)]
729 return cdist(positions1, positions2, metric = 'euclidean')
730
731 @staticmethod
732 def minDistance(obj1, obj2, instant):
733 return MovingObject.distances(obj1, obj2, instant).min()
734
735 @staticmethod
736 def maxDistance(obj1, obj2, instant):
737 return MovingObject.distances(obj1, obj2, instant).max()
738
739 def maxSize(self):
740 '''Returns the max distance between features
741 at instant there are the most features'''
742 if hasattr(self, 'features'):
743 nFeatures = -1
744 tMaxFeatures = 0
745 for t in self.getTimeInterval():
746 n = len([f for f in self.features if f.existsAtInstant(t)])
747 if n > nFeatures:
748 nFeatures = n
749 tMaxFeatures = t
750 return MovingObject.maxDistance(self, self, tMaxFeatures)
751 else:
752 print('Load features to compute a maximum size')
753 return None
754
702 def getInstantsCrossingLane(self, p1, p2): 755 def getInstantsCrossingLane(self, p1, p2):
703 '''Returns the instant(s) 756 '''Returns the instant(s)
704 at which the object passes from one side of the segment to the other 757 at which the object passes from one side of the segment to the other
705 empty list if there is no crossing''' 758 empty list if there is no crossing'''
706 indices = self.positions.getIntersections(p1, p2) 759 indices = self.positions.getIntersections(p1, p2)
728 return Point.dot(deltap, deltav) 781 return Point.dot(deltap, deltav)
729 782
730 @staticmethod 783 @staticmethod
731 def collisionCourseCosine(movingObject1, movingObject2, instant): 784 def collisionCourseCosine(movingObject1, movingObject2, instant):
732 'A positive result indicates that the road users are getting closer' 785 'A positive result indicates that the road users are getting closer'
733 deltap = movingObject1.getPositionAtInstant(instant)-movingObject2.getPositionAtInstant(instant) 786 return Point.cosine(movingObject1.getPositionAtInstant(instant)-movingObject2.getPositionAtInstant(instant), #deltap
734 deltav = movingObject2.getVelocityAtInstant(instant)-movingObject1.getVelocityAtInstant(instant) 787 movingObject2.getVelocityAtInstant(instant)-movingObject1.getVelocityAtInstant(instant)) #deltav
735 return Point.dot(deltap, deltav)/(deltap.norm2()*deltav.norm2())
736 788
737 def plotRoadUsers(objects, colors): 789 def plotRoadUsers(objects, colors):
738 '''Colors is a PlottingPropertyValues instance''' 790 '''Colors is a PlottingPropertyValues instance'''
739 from matplotlib.pyplot import figure, axis 791 from matplotlib.pyplot import figure, axis
740 figure() 792 figure()