Mercurial > hg > nsaunier > 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() |
