comparison python/moving.py @ 636:3058e00887bc

removed all issues because of tests with None, using is instead of == or !=
author Nicolas Saunier <nicolas.saunier@polymtl.ca>
date Tue, 24 Mar 2015 18:11:28 +0100
parents 6ae68383071e
children bfaa6b95dae2
comparison
equal deleted inserted replaced
635:6ae68383071e 636:3058e00887bc
403 for spline in range(len(splines)): 403 for spline in range(len(splines)):
404 #For each spline point index 404 #For each spline point index
405 for spline_p in range(len(splines[spline])-1): 405 for spline_p in range(len(splines[spline])-1):
406 #Get closest point on spline 406 #Get closest point on spline
407 closestPoint = ppldb2p(p.x,p.y,splines[spline][spline_p][0],splines[spline][spline_p][1],splines[spline][spline_p+1][0],splines[spline][spline_p+1][1]) 407 closestPoint = ppldb2p(p.x,p.y,splines[spline][spline_p][0],splines[spline][spline_p][1],splines[spline][spline_p+1][0],splines[spline][spline_p+1][1])
408 if closestPoint == None: 408 if closestPoint is None:
409 print('Error: Spline {0}, segment {1} has identical bounds and therefore is not a vector. Projection cannot continue.'.format(spline, spline_p)) 409 print('Error: Spline {0}, segment {1} has identical bounds and therefore is not a vector. Projection cannot continue.'.format(spline, spline_p))
410 return None 410 return None
411 # check if the 411 # check if the
412 if utils.inBetween(splines[spline][spline_p][0], splines[spline][spline_p+1][0], closestPoint.x) and utils.inBetween(splines[spline][spline_p][1], splines[spline][spline_p+1][1], closestPoint.y): 412 if utils.inBetween(splines[spline][spline_p][0], splines[spline][spline_p+1][0], closestPoint.x) and utils.inBetween(splines[spline][spline_p][1], splines[spline][spline_p+1][1], closestPoint.y):
413 offsetY = Point.distanceNorm2(closestPoint, p) 413 offsetY = Point.distanceNorm2(closestPoint, p)
568 568
569 if (Interval.intersection(Interval(p1.x,p2.x,True), Interval(p3.x,p4.x,True)).empty()) or (Interval.intersection(Interval(p1.y,p2.y,True), Interval(p3.y,p4.y,True)).empty()): 569 if (Interval.intersection(Interval(p1.x,p2.x,True), Interval(p3.x,p4.x,True)).empty()) or (Interval.intersection(Interval(p1.y,p2.y,True), Interval(p3.y,p4.y,True)).empty()):
570 return None 570 return None
571 else: 571 else:
572 inter = intersection(p1, p2, p3, p4) 572 inter = intersection(p1, p2, p3, p4)
573 if (inter != None 573 if (inter is not None
574 and utils.inBetween(p1.x, p2.x, inter.x) 574 and utils.inBetween(p1.x, p2.x, inter.x)
575 and utils.inBetween(p3.x, p4.x, inter.x) 575 and utils.inBetween(p3.x, p4.x, inter.x)
576 and utils.inBetween(p1.y, p2.y, inter.y) 576 and utils.inBetween(p1.y, p2.y, inter.y)
577 and utils.inBetween(p3.y, p4.y, inter.y)): 577 and utils.inBetween(p3.y, p4.y, inter.y)):
578 return inter 578 return inter
580 return None 580 return None
581 581
582 def segmentLineIntersection(p1, p2, p3, p4): 582 def segmentLineIntersection(p1, p2, p3, p4):
583 '''Indicates if the line going through p1 and p2 intersects inside p3, p4''' 583 '''Indicates if the line going through p1 and p2 intersects inside p3, p4'''
584 inter = intersection(p1, p2, p3, p4) 584 inter = intersection(p1, p2, p3, p4)
585 if inter != None and utils.inBetween(p3.x, p4.x, inter.x) and utils.inBetween(p3.y, p4.y, inter.y): 585 if inter is not None and utils.inBetween(p3.x, p4.x, inter.x) and utils.inBetween(p3.y, p4.y, inter.y):
586 return inter 586 return inter
587 else: 587 else:
588 return None 588 return None
589 589
590 590
592 '''Class for trajectories: temporal sequence of positions 592 '''Class for trajectories: temporal sequence of positions
593 593
594 The class is iterable''' 594 The class is iterable'''
595 595
596 def __init__(self, positions=None): 596 def __init__(self, positions=None):
597 if positions != None: 597 if positions is not None:
598 self.positions = positions 598 self.positions = positions
599 else: 599 else:
600 self.positions = [[],[]] 600 self.positions = [[],[]]
601 601
602 @staticmethod 602 @staticmethod
679 self.positions[1].append(self.positions[1][-1]) 679 self.positions[1].append(self.positions[1][-1])
680 680
681 @staticmethod 681 @staticmethod
682 def _plot(positions, options = '', withOrigin = False, lastCoordinate = None, timeStep = 1, **kwargs): 682 def _plot(positions, options = '', withOrigin = False, lastCoordinate = None, timeStep = 1, **kwargs):
683 from matplotlib.pylab import plot 683 from matplotlib.pylab import plot
684 if lastCoordinate == None: 684 if lastCoordinate is None:
685 plot(positions[0][::timeStep], positions[1][::timeStep], options, **kwargs) 685 plot(positions[0][::timeStep], positions[1][::timeStep], options, **kwargs)
686 elif 0 <= lastCoordinate <= len(positions[0]): 686 elif 0 <= lastCoordinate <= len(positions[0]):
687 plot(positions[0][:lastCoordinate:timeStep], positions[1][:lastCoordinate:timeStep], options, **kwargs) 687 plot(positions[0][:lastCoordinate:timeStep], positions[1][:lastCoordinate:timeStep], options, **kwargs)
688 if withOrigin: 688 if withOrigin:
689 plot([positions[0][0]], [positions[1][0]], 'ro', **kwargs) 689 plot([positions[0][0]], [positions[1][0]], 'ro', **kwargs)
816 816
817 for i in xrange(self.length()-1): 817 for i in xrange(self.length()-1):
818 q1=self.__getitem__(i) 818 q1=self.__getitem__(i)
819 q2=self.__getitem__(i+1) 819 q2=self.__getitem__(i+1)
820 p = utils.segmentIntersection(q1, q2, p1, p2) 820 p = utils.segmentIntersection(q1, q2, p1, p2)
821 if p != None: 821 if p is not None:
822 if q1.x != q2.x: 822 if q1.x != q2.x:
823 ratio = (p.x-q1.x)/(q2.x-q1.x) 823 ratio = (p.x-q1.x)/(q2.x-q1.x)
824 elif q1.y != q2.y: 824 elif q1.y != q2.y:
825 ratio = (p.y-q1.y)/(q2.y-q1.y) 825 ratio = (p.y-q1.y)/(q2.y-q1.y)
826 else: 826 else:
838 838
839 for i in xrange(self.length()-1): 839 for i in xrange(self.length()-1):
840 q1=self.__getitem__(i) 840 q1=self.__getitem__(i)
841 q2=self.__getitem__(i+1) 841 q2=self.__getitem__(i+1)
842 p = utils.segmentLineIntersection(p1, p2, q1, q2) 842 p = utils.segmentLineIntersection(p1, p2, q1, q2)
843 if p != None: 843 if p is not None:
844 if q1.x != q2.x: 844 if q1.x != q2.x:
845 ratio = (p.x-q1.x)/(q2.x-q1.x) 845 ratio = (p.x-q1.x)/(q2.x-q1.x)
846 elif q1.y != q2.y: 846 elif q1.y != q2.y:
847 ratio = (p.y-q1.y)/(q2.y-q1.y) 847 ratio = (p.y-q1.y)/(q2.y-q1.y)
848 else: 848 else:
895 '''Sub class of trajectory for trajectories with curvilinear coordinates and lane assignements 895 '''Sub class of trajectory for trajectories with curvilinear coordinates and lane assignements
896 longitudinal coordinate is stored as first coordinate (exterior name S) 896 longitudinal coordinate is stored as first coordinate (exterior name S)
897 lateral coordiante is stored as second coordinate''' 897 lateral coordiante is stored as second coordinate'''
898 898
899 def __init__(self, S = None, Y = None, lanes = None): 899 def __init__(self, S = None, Y = None, lanes = None):
900 if S == None or Y == None or len(S) != len(Y): 900 if S is None or Y is None or len(S) != len(Y):
901 self.positions = [[],[]] 901 self.positions = [[],[]]
902 if S != None and Y != None and len(S) != len(Y): 902 if S is not None and Y is not None and len(S) != len(Y):
903 print("S and Y coordinates of different lengths\nInitializing to empty lists") 903 print("S and Y coordinates of different lengths\nInitializing to empty lists")
904 else: 904 else:
905 self.positions = [S,Y] 905 self.positions = [S,Y]
906 if lanes == None or len(lanes) != self.length(): 906 if lanes is None or len(lanes) != self.length():
907 self.lanes = [] 907 self.lanes = []
908 else: 908 else:
909 self.lanes = lanes 909 self.lanes = lanes
910 910
911 def __getitem__(self,i): 911 def __getitem__(self,i):
946 return diff 946 return diff
947 947
948 def getIntersections(self, S1, lane = None): 948 def getIntersections(self, S1, lane = None):
949 '''Returns a list of the indices at which the trajectory 949 '''Returns a list of the indices at which the trajectory
950 goes past the curvilinear coordinate S1 950 goes past the curvilinear coordinate S1
951 (in provided lane if lane != None) 951 (in provided lane if lane is not None)
952 the list is empty if there is no crossing''' 952 the list is empty if there is no crossing'''
953 indices = [] 953 indices = []
954 for i in xrange(self.length()-1): 954 for i in xrange(self.length()-1):
955 q1=self.__getitem__(i) 955 q1=self.__getitem__(i)
956 q2=self.__getitem__(i+1) 956 q2=self.__getitem__(i+1)
957 if q1[0] <= S1 < q2[0] and (lane == None or (self.lanes[i] == lane and self.lanes[i+1] == lane)): 957 if q1[0] <= S1 < q2[0] and (lane is None or (self.lanes[i] == lane and self.lanes[i+1] == lane)):
958 indices.append(i+(S1-q1[0])/(q2[0]-q1[0])) 958 indices.append(i+(S1-q1[0])/(q2[0]-q1[0]))
959 return indices 959 return indices
960 960
961 ################## 961 ##################
962 # Moving Objects 962 # Moving Objects
998 commonTimeInterval = obj1.commonTimeInterval(obj2) 998 commonTimeInterval = obj1.commonTimeInterval(obj2)
999 if commonTimeInterval.empty(): 999 if commonTimeInterval.empty():
1000 print('The two objects\' time intervals do not overlap: obj1 {} and obj2 {}'.format(obj1.getTimeInterval(), obj2.getTimeInterval())) 1000 print('The two objects\' time intervals do not overlap: obj1 {} and obj2 {}'.format(obj1.getTimeInterval(), obj2.getTimeInterval()))
1001 return None 1001 return None
1002 else: 1002 else:
1003 if num == None: 1003 if num is None:
1004 newNum = obj1.getNum() 1004 newNum = obj1.getNum()
1005 else: 1005 else:
1006 newNum = num 1006 newNum = num
1007 newTimeInterval = TimeInterval.union(obj1.getTimeInterval(), obj2.getTimeInterval()) 1007 newTimeInterval = TimeInterval.union(obj1.getTimeInterval(), obj2.getTimeInterval())
1008 # positions 1008 # positions
1133 plot(list(self.getTimeInterval()), speeds) 1133 plot(list(self.getTimeInterval()), speeds)
1134 1134
1135 @staticmethod 1135 @staticmethod
1136 def distances(obj1, obj2, instant1, _instant2 = None): 1136 def distances(obj1, obj2, instant1, _instant2 = None):
1137 from scipy.spatial.distance import cdist 1137 from scipy.spatial.distance import cdist
1138 if _instant2 == None: 1138 if _instant2 is None:
1139 instant2 = instant1 1139 instant2 = instant1
1140 else: 1140 else:
1141 instant2 = _instant2 1141 instant2 = _instant2
1142 positions1 = [f.getPositionAtInstant(instant1).astuple() for f in obj1.features if f.existsAtInstant(instant1)] 1142 positions1 = [f.getPositionAtInstant(instant1).astuple() for f in obj1.features if f.existsAtInstant(instant1)]
1143 positions2 = [f.getPositionAtInstant(instant2).astuple() for f in obj2.features if f.existsAtInstant(instant2)] 1143 positions2 = [f.getPositionAtInstant(instant2).astuple() for f in obj2.features if f.existsAtInstant(instant2)]
1227 #For each point 1227 #For each point
1228 for i in xrange(int(self.length())): 1228 for i in xrange(int(self.length())):
1229 result = getSYfromXY(self.getPositionAt(i), alignments) 1229 result = getSYfromXY(self.getPositionAt(i), alignments)
1230 1230
1231 # Error handling 1231 # Error handling
1232 if(result == None): 1232 if(result is None):
1233 print('Warning: trajectory {} at point {} {} has alignment errors (spline snapping)\nCurvilinear trajectory could not be computed'.format(self.getNum(), i, self.getPositionAt(i))) 1233 print('Warning: trajectory {} at point {} {} has alignment errors (spline snapping)\nCurvilinear trajectory could not be computed'.format(self.getNum(), i, self.getPositionAt(i)))
1234 else: 1234 else:
1235 [align, alignPoint, snappedPoint, subsegmentDistance, S, Y] = result 1235 [align, alignPoint, snappedPoint, subsegmentDistance, S, Y] = result
1236 self.curvilinearPositions.addPositionSYL(S, Y, align) 1236 self.curvilinearPositions.addPositionSYL(S, Y, align)
1237 1237
1244 for i in xrange(len(lanes)): 1244 for i in xrange(len(lanes)):
1245 if(lanes[i] != smoothed_lanes[i]): 1245 if(lanes[i] != smoothed_lanes[i]):
1246 result = getSYfromXY(self.getPositionAt(i),[alignments[smoothed_lanes[i]]]) 1246 result = getSYfromXY(self.getPositionAt(i),[alignments[smoothed_lanes[i]]])
1247 1247
1248 # Error handling 1248 # Error handling
1249 if(result == None): 1249 if(result is None):
1250 ## This can be triggered by tracking errors when the trajectory jumps around passed another alignment. 1250 ## This can be triggered by tracking errors when the trajectory jumps around passed another alignment.
1251 print(' Warning: trajectory {} at point {} {} has alignment errors during trajectory smoothing and will not be corrected.'.format(self.getNum(), i, self.getPositionAt(i))) 1251 print(' Warning: trajectory {} at point {} {} has alignment errors during trajectory smoothing and will not be corrected.'.format(self.getNum(), i, self.getPositionAt(i)))
1252 else: 1252 else:
1253 [align, alignPoint, snappedPoint, subsegmentDistance, S, Y] = result 1253 [align, alignPoint, snappedPoint, subsegmentDistance, S, Y] = result
1254 self.curvilinearPositions.setPosition(i, S, Y, align) 1254 self.curvilinearPositions.setPosition(i, S, Y, align)
1331 applies the SVM model on it''' 1331 applies the SVM model on it'''
1332 from numpy import array 1332 from numpy import array
1333 croppedImg, yCropMin, yCropMax, xCropMin, xCropMax = imageBox(img, self, instant, homography, width, height, px, py, pixelThreshold) 1333 croppedImg, yCropMin, yCropMax, xCropMin, xCropMax = imageBox(img, self, instant, homography, width, height, px, py, pixelThreshold)
1334 if len(croppedImg) > 0: # != [] 1334 if len(croppedImg) > 0: # != []
1335 hog = array([cvutils.HOG(croppedImg)], dtype = np.float32) 1335 hog = array([cvutils.HOG(croppedImg)], dtype = np.float32)
1336 if self.aggregatedSpeed < pedBikeSpeedTreshold or bikeCarSVM == None: 1336 if self.aggregatedSpeed < pedBikeSpeedTreshold or bikeCarSVM is None:
1337 self.userTypes[instant] = int(pedBikeCarSVM.predict(hog)) 1337 self.userTypes[instant] = int(pedBikeCarSVM.predict(hog))
1338 elif self.aggregatedSpeed < bikeCarSpeedTreshold: 1338 elif self.aggregatedSpeed < bikeCarSpeedTreshold:
1339 self.userTypes[instant] = int(bikeCarSVM.predict(hog)) 1339 self.userTypes[instant] = int(bikeCarSVM.predict(hog))
1340 else: 1340 else:
1341 self.userTypes[instant] = userType2Num['car'] 1341 self.userTypes[instant] = userType2Num['car']
1356 if len(self.userTypes) != self.length(): # if classification has not been done previously 1356 if len(self.userTypes) != self.length(): # if classification has not been done previously
1357 for t in self.getTimeInterval(): 1357 for t in self.getTimeInterval():
1358 if t not in self.userTypes: 1358 if t not in self.userTypes:
1359 self.classifyUserTypeHoGSVMAtInstant(images[t], pedBikeCarSVM, t, homography, width, height, bikeCarSVM, pedBikeSpeedTreshold, bikeCarSpeedThreshold, px, py, pixelThreshold) 1359 self.classifyUserTypeHoGSVMAtInstant(images[t], pedBikeCarSVM, t, homography, width, height, bikeCarSVM, pedBikeSpeedTreshold, bikeCarSpeedThreshold, px, py, pixelThreshold)
1360 # compute P(Speed|Class) 1360 # compute P(Speed|Class)
1361 if speedProbabilities == None: # equiprobable information from speed 1361 if speedProbabilities is None: # equiprobable information from speed
1362 userTypeProbabilities = {userType2Num['car']: 1., userType2Num['pedestrian']: 1., userType2Num['bicycle']: 1.} 1362 userTypeProbabilities = {userType2Num['car']: 1., userType2Num['pedestrian']: 1., userType2Num['bicycle']: 1.}
1363 else: 1363 else:
1364 userTypeProbabilities = {userType2Num[userTypename]: speedProbabilities[userTypename](self.aggregatedSpeed) for userTypename in speedProbabilities} 1364 userTypeProbabilities = {userType2Num[userTypename]: speedProbabilities[userTypename](self.aggregatedSpeed) for userTypename in speedProbabilities}
1365 # result is P(Class|Appearance) x P(Speed|Class) 1365 # result is P(Class|Appearance) x P(Speed|Class)
1366 nInstantsUserType = {userType2Num[userTypename]: 0 for userTypename in userTypeProbabilities}# number of instants the object is classified as userTypename 1366 nInstantsUserType = {userType2Num[userTypename]: 0 for userTypename in userTypeProbabilities}# number of instants the object is classified as userTypename
1378 1378
1379 TODO: areas could be a wrapper object with a contains method that would work for polygons and images (with wrapper class) 1379 TODO: areas could be a wrapper object with a contains method that would work for polygons and images (with wrapper class)
1380 skip frames at beginning/end?''' 1380 skip frames at beginning/end?'''
1381 print('not implemented/tested yet') 1381 print('not implemented/tested yet')
1382 if not hasattr(self, projectedPositions): 1382 if not hasattr(self, projectedPositions):
1383 if homography != None: 1383 if homography is not None:
1384 self.projectedPositions = obj.positions.project(homography) 1384 self.projectedPositions = obj.positions.project(homography)
1385 else: 1385 else:
1386 self.projectedPositions = obj.positions 1386 self.projectedPositions = obj.positions
1387 possibleUserTypes = {userType: 0 for userType in range(len(userTypenames))} 1387 possibleUserTypes = {userType: 0 for userType in range(len(userTypenames))}
1388 for p in self.projectedPositions: 1388 for p in self.projectedPositions:
1422 self.topLeftPositions = topLeftPositions.getPositions() 1422 self.topLeftPositions = topLeftPositions.getPositions()
1423 self.bottomRightPositions = bottomRightPositions.getPositions() 1423 self.bottomRightPositions = bottomRightPositions.getPositions()
1424 1424
1425 def computeCentroidTrajectory(self, homography = None): 1425 def computeCentroidTrajectory(self, homography = None):
1426 self.positions = self.topLeftPositions.add(self.bottomRightPositions).multiply(0.5) 1426 self.positions = self.topLeftPositions.add(self.bottomRightPositions).multiply(0.5)
1427 if homography != None: 1427 if homography is not None:
1428 self.positions = self.positions.project(homography) 1428 self.positions = self.positions.project(homography)
1429 1429
1430 def matches(self, obj, instant, matchingDistance): 1430 def matches(self, obj, instant, matchingDistance):
1431 '''Indicates if the annotation matches obj (MovingObject) 1431 '''Indicates if the annotation matches obj (MovingObject)
1432 with threshold matchingDistance 1432 with threshold matchingDistance