comparison python/moving.py @ 672:5473b7460375

moved and rationalized imports in modules
author Nicolas Saunier <nicolas.saunier@polymtl.ca>
date Tue, 26 May 2015 13:53:40 +0200
parents 93633ce122c3
children 01b89182891a
comparison
equal deleted inserted replaced
671:849f5f8bf4b9 672:5473b7460375
2 '''Libraries for moving objects, trajectories...''' 2 '''Libraries for moving objects, trajectories...'''
3 3
4 import utils, cvutils 4 import utils, cvutils
5 from base import VideoFilenameAddable 5 from base import VideoFilenameAddable
6 6
7 from math import sqrt 7 from math import sqrt, atan2, cos, sin
8 from numpy import median 8 from numpy import median, array, zeros, hypot, NaN, std
9 from matplotlib.pyplot import plot
10 from scipy.stats import scoreatpercentile
11 from scipy.spatial.distance import cdist
9 12
10 try: 13 try:
11 from shapely.geometry import Polygon, Point as shapelyPoint 14 from shapely.geometry import Polygon, Point as shapelyPoint
12 from shapely.prepared import prep 15 from shapely.prepared import prep
13 shapelyAvailable = True 16 shapelyAvailable = True
197 def divide(self, alpha): 200 def divide(self, alpha):
198 'Warning, returns a new Point' 201 'Warning, returns a new Point'
199 return Point(self.x/alpha, self.y/alpha) 202 return Point(self.x/alpha, self.y/alpha)
200 203
201 def plot(self, options = 'o', **kwargs): 204 def plot(self, options = 'o', **kwargs):
202 from matplotlib.pylab import plot
203 plot([self.x], [self.y], options, **kwargs) 205 plot([self.x], [self.y], options, **kwargs)
204 206
205 def norm2Squared(self): 207 def norm2Squared(self):
206 '''2-norm distance (Euclidean distance)''' 208 '''2-norm distance (Euclidean distance)'''
207 return self.x**2+self.y**2 209 return self.x**2+self.y**2
228 if shapelyAvailable: 230 if shapelyAvailable:
229 def asShapely(self): 231 def asShapely(self):
230 return shapelyPoint(self.x, self.y) 232 return shapelyPoint(self.x, self.y)
231 233
232 def project(self, homography): 234 def project(self, homography):
233 from numpy.core.multiarray import array
234 projected = cvutils.projectArray(homography, array([[self.x], [self.y]])) 235 projected = cvutils.projectArray(homography, array([[self.x], [self.y]]))
235 return Point(projected[0], projected[1]) 236 return Point(projected[0], projected[1])
236 237
237 def inPolygon(self, polygon): 238 def inPolygon(self, polygon):
238 '''Indicates if the point x, y is inside the polygon 239 '''Indicates if the point x, y is inside the polygon
293 def timeToCollision(p1, p2, v1, v2, collisionThreshold): 294 def timeToCollision(p1, p2, v1, v2, collisionThreshold):
294 '''Computes exact time to collision with a distance threshold 295 '''Computes exact time to collision with a distance threshold
295 The unknown of the equation is the time to reach the intersection 296 The unknown of the equation is the time to reach the intersection
296 between the relative trajectory of one road user 297 between the relative trajectory of one road user
297 and the circle of radius collisionThreshold around the other road user''' 298 and the circle of radius collisionThreshold around the other road user'''
298 from math import sqrt
299 dv = v1-v2 299 dv = v1-v2
300 dp = p1-p2 300 dp = p1-p2
301 a = dv.norm2Squared()#(v1.x-v2.x)**2 + (v1.y-v2.y)**2 301 a = dv.norm2Squared()#(v1.x-v2.x)**2 + (v1.y-v2.y)**2
302 b = 2*Point.dot(dv, dp)#2 * ((p1.x-p2.x) * (v1.x-v2.x) + (p1.y-p2.y) * (v1.y-v2.y)) 302 b = 2*Point.dot(dv, dp)#2 * ((p1.x-p2.x) * (v1.x-v2.x) + (p1.y-p2.y) * (v1.y-v2.y))
303 c = dp.norm2Squared() - collisionThreshold**2#(p1.x-p2.x)**2 + (p1.y-p2.y)**2 - collisionThreshold**2 303 c = dp.norm2Squared() - collisionThreshold**2#(p1.x-p2.x)**2 + (p1.y-p2.y)**2 - collisionThreshold**2
342 where: 342 where:
343 mode=0: incremental distance 343 mode=0: incremental distance
344 mode=1: cumulative distance 344 mode=1: cumulative distance
345 mode=2: cumulative distance with trailing distance 345 mode=2: cumulative distance with trailing distance
346 ''' 346 '''
347
348 from numpy import zeros
349 ss_spline_d = [] 347 ss_spline_d = []
350 #Prepare subsegment distances 348 #Prepare subsegment distances
351 for spline in range(len(splines)): 349 for spline in range(len(splines)):
352 ss_spline_d.append([[],[],[]]) 350 ss_spline_d.append([[],[],[]])
353 ss_spline_d[spline][0] = zeros(len(splines[spline])-1) #Incremental distance 351 ss_spline_d[spline][0] = zeros(len(splines[spline])-1) #Incremental distance
478 self.norm = norm 476 self.norm = norm
479 self.angle = angle 477 self.angle = angle
480 478
481 @staticmethod 479 @staticmethod
482 def fromPoint(p): 480 def fromPoint(p):
483 from math import atan2
484 norm = p.norm2() 481 norm = p.norm2()
485 if norm > 0: 482 if norm > 0:
486 angle = atan2(p.y, p.x) 483 angle = atan2(p.y, p.x)
487 else: 484 else:
488 angle = 0. 485 angle = 0.
491 def __add__(self, other): 488 def __add__(self, other):
492 'a norm cannot become negative' 489 'a norm cannot become negative'
493 return NormAngle(max(self.norm+other.norm, 0), self.angle+other.angle) 490 return NormAngle(max(self.norm+other.norm, 0), self.angle+other.angle)
494 491
495 def getPoint(self): 492 def getPoint(self):
496 from math import cos, sin
497 return Point(self.norm*cos(self.angle), self.norm*sin(self.angle)) 493 return Point(self.norm*cos(self.angle), self.norm*sin(self.angle))
498 494
499 495
500 def predictPositionNoLimit(nTimeSteps, initialPosition, initialVelocity, initialAcceleration = Point(0,0)): 496 def predictPositionNoLimit(nTimeSteps, initialPosition, initialVelocity, initialAcceleration = Point(0,0)):
501 '''Predicts the position in nTimeSteps at constant speed/acceleration''' 497 '''Predicts the position in nTimeSteps at constant speed/acceleration'''
525 521
526 def multiply(self, alpha): 522 def multiply(self, alpha):
527 return FlowVector(self.position.multiply(alpha), self.velocity.multiply(alpha)) 523 return FlowVector(self.position.multiply(alpha), self.velocity.multiply(alpha))
528 524
529 def plot(self, options = '', **kwargs): 525 def plot(self, options = '', **kwargs):
530 from matplotlib.pylab import plot
531 plot([self.position.x, self.position.x+self.velocity.x], [self.position.y, self.position.y+self.velocity.y], options, **kwargs) 526 plot([self.position.x, self.position.x+self.velocity.x], [self.position.y, self.position.y+self.velocity.y], options, **kwargs)
532 self.position.plot(options+'x', **kwargs) 527 self.position.plot(options+'x', **kwargs)
533 528
534 @staticmethod 529 @staticmethod
535 def similar(f1, f2, maxDistance2, maxDeltavelocity2): 530 def similar(f1, f2, maxDistance2, maxDeltavelocity2):
679 self.positions[0].append(self.positions[0][-1]) 674 self.positions[0].append(self.positions[0][-1])
680 self.positions[1].append(self.positions[1][-1]) 675 self.positions[1].append(self.positions[1][-1])
681 676
682 @staticmethod 677 @staticmethod
683 def _plot(positions, options = '', withOrigin = False, lastCoordinate = None, timeStep = 1, **kwargs): 678 def _plot(positions, options = '', withOrigin = False, lastCoordinate = None, timeStep = 1, **kwargs):
684 from matplotlib.pylab import plot
685 if lastCoordinate is None: 679 if lastCoordinate is None:
686 plot(positions[0][::timeStep], positions[1][::timeStep], options, **kwargs) 680 plot(positions[0][::timeStep], positions[1][::timeStep], options, **kwargs)
687 elif 0 <= lastCoordinate <= len(positions[0]): 681 elif 0 <= lastCoordinate <= len(positions[0]):
688 plot(positions[0][:lastCoordinate:timeStep], positions[1][:lastCoordinate:timeStep], options, **kwargs) 682 plot(positions[0][:lastCoordinate:timeStep], positions[1][:lastCoordinate:timeStep], options, **kwargs)
689 if withOrigin: 683 if withOrigin:
708 702
709 def getYCoordinates(self): 703 def getYCoordinates(self):
710 return self.positions[1] 704 return self.positions[1]
711 705
712 def asArray(self): 706 def asArray(self):
713 from numpy.core.multiarray import array
714 return array(self.positions) 707 return array(self.positions)
715 708
716 def xBounds(self): 709 def xBounds(self):
717 # look for function that does min and max in one pass 710 # look for function that does min and max in one pass
718 return Interval(min(self.getXCoordinates()), max(self.getXCoordinates())) 711 return Interval(min(self.getXCoordinates()), max(self.getXCoordinates()))
755 def norm(self): 748 def norm(self):
756 '''Returns the list of the norms at each instant''' 749 '''Returns the list of the norms at each instant'''
757 # def add(x, y): return x+y 750 # def add(x, y): return x+y
758 # sq = map(add, [x*x for x in self.positions[0]], [y*y for y in self.positions[1]]) 751 # sq = map(add, [x*x for x in self.positions[0]], [y*y for y in self.positions[1]])
759 # return sqrt(sq) 752 # return sqrt(sq)
760 from numpy import hypot
761 return hypot(self.positions[0], self.positions[1]) 753 return hypot(self.positions[0], self.positions[1])
762 754
763 # def cumulatedDisplacement(self): 755 # def cumulatedDisplacement(self):
764 # 'Returns the sum of the distances between each successive point' 756 # 'Returns the sum of the distances between each successive point'
765 # displacement = 0 757 # displacement = 0
1081 else: 1073 else:
1082 return None 1074 return None
1083 1075
1084 def plotCurvilinearPositions(self, lane = None, options = '', withOrigin = False, **kwargs): 1076 def plotCurvilinearPositions(self, lane = None, options = '', withOrigin = False, **kwargs):
1085 if hasattr(self, 'curvilinearPositions'): 1077 if hasattr(self, 'curvilinearPositions'):
1086 from matplotlib.pylab import plot
1087 from numpy import NaN
1088 if lane is None: 1078 if lane is None:
1089 plot(list(self.getTimeInterval()), self.curvilinearPositions.positions[0], options, **kwargs) 1079 plot(list(self.getTimeInterval()), self.curvilinearPositions.positions[0], options, **kwargs)
1090 if withOrigin: 1080 if withOrigin:
1091 plot([self.getFirstInstant()], [self.curvilinearPositions.positions[0][0]], 'ro', **kwargs) 1081 plot([self.getFirstInstant()], [self.curvilinearPositions.positions[0][0]], 'ro', **kwargs)
1092 else: 1082 else:
1177 1167
1178 def play(self, videoFilename, homography = None, undistort = False, intrinsicCameraMatrix = None, distortionCoefficients = None, undistortedImageMultiplication = 1.): 1168 def play(self, videoFilename, homography = None, undistort = False, intrinsicCameraMatrix = None, distortionCoefficients = None, undistortedImageMultiplication = 1.):
1179 cvutils.displayTrajectories(videoFilename, [self], homography = homography, firstFrameNum = self.getFirstInstant(), lastFrameNumArg = self.getLastInstant(), undistort = undistort, intrinsicCameraMatrix = intrinsicCameraMatrix, distortionCoefficients = distortionCoefficients, undistortedImageMultiplication = undistortedImageMultiplication) 1169 cvutils.displayTrajectories(videoFilename, [self], homography = homography, firstFrameNum = self.getFirstInstant(), lastFrameNumArg = self.getLastInstant(), undistort = undistort, intrinsicCameraMatrix = intrinsicCameraMatrix, distortionCoefficients = distortionCoefficients, undistortedImageMultiplication = undistortedImageMultiplication)
1180 1170
1181 def speedDiagnostics(self, framerate = 1., display = False): 1171 def speedDiagnostics(self, framerate = 1., display = False):
1182 from numpy import std
1183 from scipy.stats import scoreatpercentile
1184 speeds = framerate*self.getSpeeds() 1172 speeds = framerate*self.getSpeeds()
1185 coef = utils.linearRegression(range(len(speeds)), speeds) 1173 coef = utils.linearRegression(range(len(speeds)), speeds)
1186 print('min/5th perc speed: {} / {}\nspeed diff: {}\nspeed stdev: {}\nregression: {}'.format(min(speeds), scoreatpercentile(speeds, 5), speeds[-2]-speeds[1], std(speeds), coef[0])) 1174 print('min/5th perc speed: {} / {}\nspeed diff: {}\nspeed stdev: {}\nregression: {}'.format(min(speeds), scoreatpercentile(speeds, 5), speeds[-2]-speeds[1], std(speeds), coef[0]))
1187 if display: 1175 if display:
1188 from matplotlib.pyplot import figure, plot, axis 1176 from matplotlib.pyplot import figure, axis
1189 figure(1) 1177 figure(1)
1190 self.plot() 1178 self.plot()
1191 axis('equal') 1179 axis('equal')
1192 figure(2) 1180 figure(2)
1193 plot(list(self.getTimeInterval()), speeds) 1181 plot(list(self.getTimeInterval()), speeds)
1212 @staticmethod 1200 @staticmethod
1213 def distances(obj1, obj2, instant1, _instant2 = None): 1201 def distances(obj1, obj2, instant1, _instant2 = None):
1214 '''Returns the distances between all features of the 2 objects 1202 '''Returns the distances between all features of the 2 objects
1215 at the same instant instant1 1203 at the same instant instant1
1216 or at instant1 and instant2''' 1204 or at instant1 and instant2'''
1217 from scipy.spatial.distance import cdist
1218 if _instant2 is None: 1205 if _instant2 is None:
1219 instant2 = instant1 1206 instant2 = instant1
1220 else: 1207 else:
1221 instant2 = _instant2 1208 instant2 = _instant2
1222 positions1 = [f.getPositionAtInstant(instant1).astuple() for f in obj1.features if f.existsAtInstant(instant1)] 1209 positions1 = [f.getPositionAtInstant(instant1).astuple() for f in obj1.features if f.existsAtInstant(instant1)]
1264 1251
1265 Returns the smallest time difference when the object positions are within collisionDistanceThreshold''' 1252 Returns the smallest time difference when the object positions are within collisionDistanceThreshold'''
1266 #for i in xrange(int(obj1.length())-1): 1253 #for i in xrange(int(obj1.length())-1):
1267 # for j in xrange(int(obj2.length())-1): 1254 # for j in xrange(int(obj2.length())-1):
1268 # inter = segmentIntersection(obj1.getPositionAt(i), obj1.getPositionAt(i+1), obj2.getPositionAt(i), obj2.getPositionAt(i+1)) 1255 # inter = segmentIntersection(obj1.getPositionAt(i), obj1.getPositionAt(i+1), obj2.getPositionAt(i), obj2.getPositionAt(i+1))
1269 from scipy.spatial.distance import cdist
1270 from numpy import zeros
1271 positions1 = [p.astuple() for p in obj1.getPositions()] 1256 positions1 = [p.astuple() for p in obj1.getPositions()]
1272 positions2 = [p.astuple() for p in obj2.getPositions()] 1257 positions2 = [p.astuple() for p in obj2.getPositions()]
1273 pets = zeros((int(obj1.length()), int(obj2.length()))) 1258 pets = zeros((int(obj1.length()), int(obj2.length())))
1274 for i,t1 in enumerate(obj1.getTimeInterval()): 1259 for i,t1 in enumerate(obj1.getTimeInterval()):
1275 for j,t2 in enumerate(obj2.getTimeInterval()): 1260 for j,t2 in enumerate(obj2.getTimeInterval()):
1337 '''Computes the trajectory as the mean of all features 1322 '''Computes the trajectory as the mean of all features
1338 if a feature exists, its position is 1323 if a feature exists, its position is
1339 1324
1340 Warning work in progress 1325 Warning work in progress
1341 TODO? not use the first/last 1-.. positions''' 1326 TODO? not use the first/last 1-.. positions'''
1342 from numpy import array, median
1343 nFeatures = len(self.features) 1327 nFeatures = len(self.features)
1344 if nFeatures == 0: 1328 if nFeatures == 0:
1345 print('Empty object features\nCannot compute smooth trajectory') 1329 print('Empty object features\nCannot compute smooth trajectory')
1346 else: 1330 else:
1347 # compute the relative position vectors 1331 # compute the relative position vectors
1407 self.userTypes = {} 1391 self.userTypes = {}
1408 1392
1409 def classifyUserTypeHoGSVMAtInstant(self, img, pedBikeCarSVM, instant, homography, width, height, bikeCarSVM = None, pedBikeSpeedTreshold = float('Inf'), bikeCarSpeedThreshold = float('Inf'), px = 0.2, py = 0.2, pixelThreshold = 800): 1393 def classifyUserTypeHoGSVMAtInstant(self, img, pedBikeCarSVM, instant, homography, width, height, bikeCarSVM = None, pedBikeSpeedTreshold = float('Inf'), bikeCarSpeedThreshold = float('Inf'), px = 0.2, py = 0.2, pixelThreshold = 800):
1410 '''Extract the image box around the object and 1394 '''Extract the image box around the object and
1411 applies the SVM model on it''' 1395 applies the SVM model on it'''
1412 from numpy import array
1413 croppedImg, yCropMin, yCropMax, xCropMin, xCropMax = imageBox(img, self, instant, homography, width, height, px, py, pixelThreshold) 1396 croppedImg, yCropMin, yCropMax, xCropMin, xCropMax = imageBox(img, self, instant, homography, width, height, px, py, pixelThreshold)
1414 if len(croppedImg) > 0: # != [] 1397 if len(croppedImg) > 0: # != []
1415 hog = array([cvutils.HOG(croppedImg)], dtype = np.float32) 1398 hog = array([cvutils.HOG(croppedImg)], dtype = np.float32)
1416 if self.aggregatedSpeed < pedBikeSpeedTreshold or bikeCarSVM is None: 1399 if self.aggregatedSpeed < pedBikeSpeedTreshold or bikeCarSVM is None:
1417 self.userTypes[instant] = int(pedBikeCarSVM.predict(hog)) 1400 self.userTypes[instant] = int(pedBikeCarSVM.predict(hog))