Mercurial Hosting > traffic-intelligence
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() |