Mercurial Hosting > traffic-intelligence
changeset 1177:aa88acf06876
rewrote object concatenation method, cleaner
author | Nicolas Saunier <nicolas.saunier@polymtl.ca> |
---|---|
date | Thu, 24 Mar 2022 16:07:51 -0400 |
parents | 5874ece33637 |
children | ee3eaf902b83 7117a31555c1 |
files | trafficintelligence/moving.py trafficintelligence/storage.py trafficintelligence/tests/moving.txt |
diffstat | 3 files changed, 101 insertions(+), 53 deletions(-) [+] |
line wrap: on
line diff
--- a/trafficintelligence/moving.py Thu Feb 17 10:55:11 2022 -0500 +++ b/trafficintelligence/moving.py Thu Mar 24 16:07:51 2022 -0400 @@ -750,8 +750,8 @@ def append(self,other): '''adds positions of other to the trajectory (in-place modification)''' - for p in other: - self.addPosition(p) + for i in range(2): + self.positions[i] += other.positions[i] def setPositionXY(self, i, x, y): if i < self.__len__(): @@ -767,7 +767,7 @@ def addPosition(self, p): self.addPositionXY(p.x, p.y) - + def duplicateLastPosition(self): self.positions[0].append(self.positions[0][-1]) self.positions[1].append(self.positions[1][-1]) @@ -1174,6 +1174,10 @@ else: return None + def append(self, other): + Trajectory.append(self, other) + self.lanes.append(other.getLanes()) + def addPositionSYL(self, s, y, lane = None): self.addPositionXY(s,y) self.lanes.append(lane) @@ -1312,59 +1316,61 @@ inter, self.positions, self.velocities = MovingObject.aggregateTrajectories(self.features, self.getTimeInterval()) @staticmethod - def concatenate(obj1, obj2, num = None, newFeatureNum = None, minFeatureLength = 5): + def concatenate(obj1, obj2, num = None, newFeatureNum = None): '''Concatenates two objects, whether overlapping temporally or not - Positions will be recomputed features are merged - Otherwise, only featureNumbers and/or features will be merged - minFeatureLength enforces a minimum length to avoid small features - (and smaller velocities that are not saved)''' + Positions will be recomputed if features are merged + Otherwise, only featureNumbers and/or features will be merged''' if num is None: newNum = obj1.getNum() else: newNum = num commonTimeInterval = obj1.commonTimeInterval(obj2) - if commonTimeInterval.empty(): - #print('The two objects\' time intervals do not overlap: obj1 {} and obj2 {}'.format(obj1.getTimeInterval(), obj2.getTimeInterval())) - emptyInterval = TimeInterval(min(obj1.getLastInstant(),obj2.getLastInstant()), max(obj1.getFirstInstant(),obj2.getFirstInstant())) - if obj1.existsAtInstant(emptyInterval.last): - firstObject = obj2 - secondObject = obj1 + emptyInterval = TimeInterval(min(obj1.getLastInstant(),obj2.getLastInstant()), max(obj1.getFirstInstant(),obj2.getFirstInstant())) + if commonTimeInterval.empty() and emptyInterval.length() >= 3: + if newFeatureNum is None: + print('Not merging objects {} and {}, missing new feature number'.format(obj1.getNum(),obj2.getNum())) + return None, None else: - firstObject = obj1 - secondObject = obj2 - v = (secondObject.getPositionAtInstant(emptyInterval.last)-firstObject.getPositionAtInstant(emptyInterval.first)).divide(emptyInterval.length()-1) - positions = copy.deepcopy(firstObject.getPositions()) - velocities = copy.deepcopy(firstObject.getPositions()) - featurePositions = Trajectory() - featureVelocities = Trajectory() - p = firstObject.getPositionAtInstant(emptyInterval.first)+v - for t in range(emptyInterval.first+1, emptyInterval.last+1): - positions.addPosition(p) - velocities.addPosition(v) - featurePositions.addPosition(p) - featureVelocities.addPosition(v) - p=p+v - for t in secondObject.getTimeInterval(): - p = secondObject.getPositionAtInstant(t) - v = secondObject.getVelocityAtInstant(t) - positions.addPosition(p) - velocities.addPosition(v) - if featurePositions.length() < minFeatureLength: + if obj1.existsAtInstant(emptyInterval.last): + firstObject = obj2 + secondObject = obj1 + else: + firstObject = obj1 + secondObject = obj2 + v = (secondObject.getPositionAtInstant(emptyInterval.last)-firstObject.getPositionAtInstant(emptyInterval.first)).divide(emptyInterval.length()-1) + positions = copy.deepcopy(firstObject.getPositions()) + velocities = copy.deepcopy(firstObject.getPositions()) + featurePositions = Trajectory() + featureVelocities = Trajectory() + p = firstObject.getPositionAtInstant(emptyInterval.first) + # init new feature with position at last instant of 1st obj + featurePositions.addPosition(p) + featureVelocities.addPosition(v) + for t in range(emptyInterval.first+1, emptyInterval.last): + p=p+v + positions.addPosition(p) + velocities.addPosition(v) featurePositions.addPosition(p) featureVelocities.addPosition(v) - newObject = MovingObject(newNum, TimeInterval(firstObject.getFirstInstant(), secondObject.getLastInstant()), positions, velocities, nObjects = 1) - if hasattr(obj1, 'featureNumbers') and hasattr(obj2, 'featureNumbers'): - if newFeatureNum is not None: + # last position to feature + p = secondObject.getPositionAtInstant(emptyInterval.last) + v = secondObject.getVelocityAtInstant(emptyInterval.last) + featurePositions.addPosition(p) + featureVelocities.addPosition(v) + # copy second trajectory + positions.append(secondObject.getPositions()) + velocities.append(secondObject.getVelocities()) + newObject = MovingObject(newNum, TimeInterval(firstObject.getFirstInstant(), secondObject.getLastInstant()), positions, velocities, nObjects = 1) + newFeature = MovingObject(newFeatureNum, emptyInterval, featurePositions, featureVelocities) + if hasattr(obj1, 'featureNumbers') and hasattr(obj2, 'featureNumbers'): newObject.featureNumbers = obj1.featureNumbers+obj2.featureNumbers+[newFeatureNum] - else: - print('Issue, new created feature has no num id') - if obj1.hasFeatures() and obj2.hasFeatures(): - newObject.features = obj1.getFeatures()+obj2.getFeatures()+[MovingObject(newFeatureNum, TimeInterval(emptyInterval.first+1, emptyInterval.first+featurePositions.length()), featurePositions, featureVelocities)] - newObject.updatePositions() + if obj1.hasFeatures() and obj2.hasFeatures(): + newObject.features = obj1.getFeatures()+obj2.getFeatures()+[newFeature] else: # time intervals overlap newTimeInterval = TimeInterval.union(obj1.getTimeInterval(), obj2.getTimeInterval()) newObject = MovingObject(newNum, newTimeInterval, nObjects = 1) # hypothesis is that it's the same object being reunited + newFeature = None if hasattr(obj1, 'featureNumbers') and hasattr(obj2, 'featureNumbers'): newObject.featureNumbers = obj1.featureNumbers+obj2.featureNumbers if obj1.hasFeatures() and obj2.hasFeatures(): @@ -1376,7 +1382,7 @@ if obj1.getUserType() != obj2.getUserType(): print('The two moving objects have different user types: obj1 {} obj2 {}'.format(userTypeNames[obj1.getUserType()], userTypeNames[obj2.getUserType()])) newObject.setUserType(obj1.getUserType()) - return newObject + return newObject, newFeature def getObjectInTimeInterval(self, inter): '''Returns a new object extracted from self,
--- a/trafficintelligence/storage.py Thu Feb 17 10:55:11 2022 -0500 +++ b/trafficintelligence/storage.py Thu Mar 24 16:07:51 2022 -0400 @@ -1479,8 +1479,8 @@ '''Loads information from configuration file then checks what was passed on the command line for override (eg video filename and database filename''' - parentPath = Path(args.configFilename).parent if args.configFilename is not None: # consider there is a configuration file + parentPath = Path(args.configFilename).parent params = ProcessParameters(args.configFilename) videoFilename = params.videoFilename databaseFilename = params.databaseFilename @@ -1494,6 +1494,7 @@ undistort = params.undistort firstFrameNum = params.firstFrameNum else: + params = None invHomography = None undistort = False intrinsicCameraMatrix = None
--- a/trafficintelligence/tests/moving.txt Thu Feb 17 10:55:11 2022 -0500 +++ b/trafficintelligence/tests/moving.txt Thu Mar 24 16:07:51 2022 -0400 @@ -137,6 +137,9 @@ >>> t3 = Trajectory.fromPointList([(92.2, 102.9), (56.7, 69.6), (56.7, 69.6)]) >>> t1 == t3 False +>>> t1.append(t2) +>>> t1.length() +4 >>> left = Trajectory.fromPointList([(92.291666666666686, 102.99239033124439), (56.774193548387103, 69.688898836168306)]) >>> middle = Trajectory.fromPointList([(87.211021505376351, 93.390778871978512), (59.032258064516128, 67.540286481647257)]) @@ -151,8 +154,8 @@ >>> Trajectory().length() 0 >>> t1 = Trajectory([[0.5,1.5,2.5],[0.5,3.5,6.5]]) ->>> t1.length() == 3. -True +>>> t1.length() +3 >>> t1[1] (1.500000,3.500000) @@ -298,9 +301,15 @@ >>> o2.features = [o2] >>> o3 = MovingObject.generate(3, Point(2., 2.), Point(1., 1.), TimeInterval(2,12)) >>> o3.features = [o3] ->>> o13 = MovingObject.concatenate(o1, o3, 4) ->>> o13.getNum() -4 +>>> o4 = MovingObject.generate(4, Point(4., 4.), Point(1., 1.), TimeInterval(11,20)) +>>> o4.features = [o4] +>>> o5 = MovingObject.generate(5, Point(5., 5.), Point(1., 1.), TimeInterval(12,22)) +>>> o5.features = [o5] + +>>> objNum = 14 +>>> o13, f13 = MovingObject.concatenate(o1, o3, objNum) +>>> o13.getNum() == objNum +True >>> o13.getTimeInterval() == TimeInterval(0,12) True >>> t=5 @@ -309,7 +318,7 @@ >>> len(o13.getFeatures()) 2 ->>> o12 = MovingObject.concatenate(o1, o2, 5, minFeatureLength = 6) +>>> o12, f12 = MovingObject.concatenate(o1, o2, 15, 15) >>> o12.getTimeInterval() == TimeInterval(o1.getFirstInstant(), o2.getLastInstant()) True >>> v = o12.getVelocityAtInstant(12) @@ -319,9 +328,41 @@ True >>> len(o12.getFeatures()) 3 ->>> f = o12.getFeatures()[-1] ->>> f.length() -6.0 +>>> f12.length() +5.0 +>>> f12.getPositions().length() +5 +>>> f12.getVelocities().length() +5 + +>>> o14, f14 = MovingObject.concatenate(o1, o4, 16) +>>> len(o14.getFeatures()) +2 +>>> o14.getPositionAtInstant(10) == o1.getPositionAtInstant(10) +True +>>> o14.getPositionAtInstant(11) == o4.getPositionAtInstant(11) +True + +>>> o15, f15 = MovingObject.concatenate(o1, o5, 17, 17) +>>> len(o15.getFeatures()) +3 +>>> f15.length() +3.0 +>>> o15.getFeatures()[-1] == f15 +True +>>> o1.getPositionAtInstant(10) == o15.getPositionAtInstant(10) +True +>>> f15.getPositionAtInstant(11) == o15.getPositionAtInstant(11) +True +>>> o5.getPositionAtInstant(12) == o15.getPositionAtInstant(12) +True +>>> o15.updatePositions() +>>> o1.getPositionAtInstant(10) == o15.getPositionAtInstant(10) +True +>>> f15.getPositionAtInstant(11) == o15.getPositionAtInstant(11) +True +>>> o5.getPositionAtInstant(12) == o15.getPositionAtInstant(12) +True >>> o1 = MovingObject.generate(1, Point(0., 2.), Point(0., 1.), TimeInterval(0,2)) >>> o1.classifyUserTypeSpeedMotorized(0.5, np.median)