Mercurial Hosting > traffic-intelligence
changeset 1110:6bbcd9433732
formatting and addition of one method to CurvilinearTrajectory
author | Nicolas Saunier <nicolas.saunier@polymtl.ca> |
---|---|
date | Mon, 06 May 2019 16:16:28 -0400 |
parents | 6e8ab471ebd4 |
children | 345cd9cd62d8 |
files | trafficintelligence/moving.py trafficintelligence/tests/moving.txt |
diffstat | 2 files changed, 41 insertions(+), 31 deletions(-) [+] |
line wrap: on
line diff
--- a/trafficintelligence/moving.py Tue Apr 16 11:58:23 2019 -0400 +++ b/trafficintelligence/moving.py Mon May 06 16:16:28 2019 -0400 @@ -273,7 +273,7 @@ def angle(self): return atan2(self.y, self.x) - + def norm2Squared(self): '''2-norm distance (Euclidean distance)''' return self.x**2+self.y**2 @@ -284,7 +284,7 @@ def norm1(self): return abs(self.x)+abs(self.y) - + def normMax(self): return max(abs(self.x),abs(self.y)) @@ -346,7 +346,7 @@ @staticmethod def parallel(p1, p2): return Point.cross(p1, p2) == 0. - + @staticmethod def cosine(p1, p2): return Point.dot(p1,p2)/(p1.norm2()*p2.norm2()) @@ -465,8 +465,9 @@ except ZeroDivisionError: print('Error: Division by zero in ppldb2p. Please report this error with the full traceback:') print('qx={0}, qy={1}, p0x={2}, p0y={3}, p1x={4}, p1y={5}...'.format(qx, qy, p0x, p0y, p1x, p1y)) - import pdb; pdb.set_trace() - return Point(X,Y) + import pdb; + pdb.set_trace() + return Point(X, Y) def getSYfromXY(p, alignments, goodEnoughAlignmentDistance = 0.5): ''' Snap a point p to its nearest subsegment of it's nearest alignment (from the list alignments). @@ -541,14 +542,14 @@ print('Curvilinear point {} is past the end of the alignement'.format((s, y, alignmentNum))) return None - + class NormAngle(object): '''Alternate encoding of a point, by its norm and orientation''' def __init__(self, norm, angle): self.norm = norm self.angle = angle - + @staticmethod def fromPoint(p): norm = p.norm2() @@ -598,7 +599,7 @@ def plot(self, options = '', **kwargs): plot([self.position.x, self.position.x+self.velocity.x], [self.position.y, self.position.y+self.velocity.y], options, **kwargs) self.position.plot(options+'x', **kwargs) - + @staticmethod def similar(f1, f2, maxDistance2, maxDeltavelocity2): return (f1.position-f2.position).norm2Squared()<maxDistance2 and (f1.velocity-f2.velocity).norm2Squared()<maxDeltavelocity2 @@ -625,7 +626,7 @@ # [dp2.y, -dp2.x]]) # B = matrix([[dp1.y*p1.x-dp1.x*p1.y], # [dp2.y*p2.x-dp2.x*p2.y]]) - + # if linalg.det(A) == 0: # return None # else: @@ -655,7 +656,7 @@ return inter else: return None - + class Trajectory(object): '''Class for trajectories: temporal sequence of positions @@ -792,15 +793,15 @@ def asArray(self): return array(self.positions) - + def xBounds(self): # look for function that does min and max in one pass return Interval(min(self.getXCoordinates()), max(self.getXCoordinates())) - + def yBounds(self): # look for function that does min and max in one pass return Interval(min(self.getYCoordinates()), max(self.getYCoordinates())) - + def add(self, traj2): '''Returns a new trajectory of the same length''' if self.length() != traj2.length(): @@ -951,7 +952,7 @@ Returns an empty list if there is no crossing''' indices = [] intersections = [] - + for i in range(self.length()-1): q1=self.__getitem__(i) q2=self.__getitem__(i+1) @@ -1058,7 +1059,7 @@ self.lanes = [None]*int(self.length()) else: self.lanes = lanes - + @staticmethod def generate(s, v, nPoints, lane, y = 0): '''s is initial position, v is velocity @@ -1134,7 +1135,7 @@ def getSCoordinates(self): return self.getXCoordinates() - + def getLanes(self): return self.lanes @@ -1164,6 +1165,10 @@ 'Adds position in the point format for curvilinear of list with 3 values' self.addPositionSYL(p[0], p[1], p[2]) + def duplicateLastPosition(self): + super(CurvilinearTrajectory, self).duplicateLastPosition() + self.lanes.append(self.lanes[-1]) + def setPosition(self, i, s, y, lane): self.setPositionXY(i, s, y) if i < self.__len__(): @@ -1215,7 +1220,7 @@ def predict(self, hog): return userType2Num['car'] carClassifier = CarClassifier() - + class MovingObject(STObject, VideoFilenameAddable): '''Class for moving objects: a spatio-temporal object with a trajectory and a geometry (constant volume over time) @@ -1235,7 +1240,7 @@ self.setNObjects(nObjects) # a feature has None for nObjects self.features = None # compute bounding polygon from trajectory - + @staticmethod def croppedTimeInterval(obj, value, after = True): newTimeInterval = TimeInterval(obj.getFirstInstant(), min(value, obj.getLastInstant())) if after else TimeInterval(max(obj.getFirstInstant(), value), obj.getLastInstant()) @@ -1519,7 +1524,7 @@ print('Object {} does not exist at {}'.format(self.getNum(), t)) else: print('Object {} has no curvilinear positions'.format(self.getNum())) - + def setUserType(self, userType): self.userType = userType @@ -1532,7 +1537,7 @@ else: print('Number of objects represented by object {} must be greater or equal to 1 ({})'.format(self.getNum(), nObjects)) self.nObjects = None - + def setFeatures(self, features, featuresOrdered = False): '''Sets the features in the features field based on featureNumbers if not all features are loaded from 0, one needs to renumber in a dict''' @@ -1591,7 +1596,7 @@ if speeds is None: speeds = self.getSpeeds(nInstantsIgnoredAtEnds) return savgol_filter(speeds, window_length, polyorder, 1, delta, axis, mode, cval) - + def getSpeedIndicator(self): from indicators import SeverityIndicator return SeverityIndicator('Speed', {t:self.getVelocityAtInstant(t).norm2() for t in self.getTimeInterval()}) @@ -1622,10 +1627,10 @@ def getXCoordinates(self): return self.positions.getXCoordinates() - + def getYCoordinates(self): return self.positions.getYCoordinates() - + def plot(self, options = '', withOrigin = False, timeStep = 1, withFeatures = False, withIds = False, **kwargs): if withIds: objNum = self.getNum() @@ -1690,7 +1695,7 @@ positions1 = [f.getPositionAtInstant(instant1).astuple() for f in obj1.features if f.existsAtInstant(instant1)] positions2 = [f.getPositionAtInstant(instant2).astuple() for f in obj2.features if f.existsAtInstant(instant2)] return cdist(positions1, positions2, metric = 'euclidean') - + @staticmethod def minDistance(obj1, obj2, instant1, instant2 = None): return MovingObject.distances(obj1, obj2, instant1, instant2).min() @@ -1714,11 +1719,11 @@ else: print('Load features to compute a maximum size') return None - + def setRoutes(self, startRouteID, endRouteID): self.startRouteID = startRouteID self.endRouteID = endRouteID - + def getInstantsCrossingLane(self, p1, p2): '''Returns the instant(s) at which the object passes from one side of the segment to the other @@ -1734,7 +1739,7 @@ lcss.similarities(proto.getMovingObject().getPositions().asArray().T, self.getPositions().asArray().T) similarities = lcss.similarityTable[-1, :-1].astype(float) self.prototypeSimilarities.append(similarities/minimum(arange(1., len(similarities)+1), proto.getMovingObject().length()*ones(len(similarities)))) - + @staticmethod def computePET(obj1, obj2, collisionDistanceThreshold): '''Post-encroachment time based on distance threshold @@ -1811,7 +1816,7 @@ '''Classifies slow and fast road users slow: non-motorized -> pedestrians fast: motorized -> cars - + aggregationFunc can be any function that can be applied to a vector of speeds, including percentile: aggregationFunc = lambda x: percentile(x, percentileFactor) # where percentileFactor is 85 for 85th percentile''' speeds = self.getSpeeds(nInstantsIgnoredAtEnds) @@ -1970,7 +1975,7 @@ return self.filename == p2.filename and self.num == p2.num and self.trajectoryType == p2.trajectoryType def __hash__(self): return hash((self.filename, self.num, self.trajectoryType)) - + ################## # Annotations ################## @@ -2100,7 +2105,7 @@ for a,o in matches.items(): gtMatches[a.getNum()][t] = o.getNum() toMatches[o.getNum()][t] = a.getNum() - + # compute metrics elements ct += len(matches) mt += nGTs-len(matches) @@ -2123,7 +2128,7 @@ print('{} {}'.format(type(mm), mm.getNum())) # some object mismatches may appear twice mme += len(set(mismatches)) - + if ct > 0: motp = dist/ct else:
--- a/trafficintelligence/tests/moving.txt Tue Apr 16 11:58:23 2019 -0400 +++ b/trafficintelligence/tests/moving.txt Mon May 06 16:16:28 2019 -0400 @@ -232,6 +232,11 @@ >>> o.interpolateCurvilinearPositions(10.7) # doctest:+ELLIPSIS [14.09999..., 0.69999..., 'a'] +>>> t1 = CurvilinearTrajectory.generate(3, 1., 10, 'b') +>>> t1.duplicateLastPosition() +>>> t1[-1] == t1[-2] +True + >>> a = Trajectory.generate(Point(0.,0.), Point(10.,0.), 4) >>> t = Trajectory.generate(Point(0.1,-1.), Point(1.,0.), 22) >>> prepareAlignments([a])