Mercurial > hg > nsaunier > traffic-intelligence
comparison python/moving.py @ 1012:01db14e947e4
resolved
| author | Wendlasida |
|---|---|
| date | Fri, 01 Jun 2018 10:47:49 -0400 |
| parents | 4f0312bee393 cc7c6b821ae6 |
| children | d6f121ded971 |
comparison
equal
deleted
inserted
replaced
| 1011:4f0312bee393 | 1012:01db14e947e4 |
|---|---|
| 120 | 120 |
| 121 def __iter__(self): | 121 def __iter__(self): |
| 122 self.iterInstantNum = -1 | 122 self.iterInstantNum = -1 |
| 123 return self | 123 return self |
| 124 | 124 |
| 125 def next(self): | 125 def __next__(self): |
| 126 if self.iterInstantNum >= self.length()-1: | 126 if self.iterInstantNum >= self.length()-1: |
| 127 raise StopIteration | 127 raise StopIteration |
| 128 else: | 128 else: |
| 129 self.iterInstantNum += 1 | 129 self.iterInstantNum += 1 |
| 130 return self[self.iterInstantNum] | 130 return self[self.iterInstantNum] |
| 169 def getFirstInstant(self): | 169 def getFirstInstant(self): |
| 170 return self.timeInterval.first | 170 return self.timeInterval.first |
| 171 | 171 |
| 172 def getLastInstant(self): | 172 def getLastInstant(self): |
| 173 return self.timeInterval.last | 173 return self.timeInterval.last |
| 174 | |
| 175 def setFirstInstant(self, t): | |
| 176 if t <= self.timeInterval.last: | |
| 177 self.timeInterval.first = t | |
| 178 else: | |
| 179 print('new first instant is after last, not changing') | |
| 180 | |
| 181 def setLastInstant(self, t): | |
| 182 if t >= self.timeInterval.first: | |
| 183 self.timeInterval.last = t | |
| 184 else: | |
| 185 print('new last instant is before first, not changing') | |
| 174 | 186 |
| 175 def getTimeInterval(self): | 187 def getTimeInterval(self): |
| 176 return self.timeInterval | 188 return self.timeInterval |
| 177 | 189 |
| 178 def existsAtInstant(self, t): | 190 def existsAtInstant(self, t): |
| 377 '''Optimized tests of a series of points within (Shapely) polygon (not prepared)''' | 389 '''Optimized tests of a series of points within (Shapely) polygon (not prepared)''' |
| 378 if type(polygon) == PreparedGeometry: | 390 if type(polygon) == PreparedGeometry: |
| 379 prepared_polygon = polygon | 391 prepared_polygon = polygon |
| 380 else: | 392 else: |
| 381 prepared_polygon = prep(polygon) | 393 prepared_polygon = prep(polygon) |
| 382 return filter(prepared_polygon.contains, points) | 394 return list(filter(prepared_polygon.contains, points)) |
| 383 | 395 |
| 384 # Functions for coordinate transformation | 396 # Functions for coordinate transformation |
| 385 # From Paul St-Aubin's PVA tools | 397 # From Paul St-Aubin's PVA tools |
| 386 def subsec_spline_dist(splines): | 398 def subsec_spline_dist(splines): |
| 387 ''' Prepare list of spline subsegments from a spline list. | 399 ''' Prepare list of spline subsegments from a spline list. |
| 415 | 427 |
| 416 def prepareSplines(splines): | 428 def prepareSplines(splines): |
| 417 'Approximates slope singularity by giving some slope roundoff; account for roundoff error' | 429 'Approximates slope singularity by giving some slope roundoff; account for roundoff error' |
| 418 for spline in splines: | 430 for spline in splines: |
| 419 p1 = spline[0] | 431 p1 = spline[0] |
| 420 for i in xrange(len(spline)-1): | 432 for i in range(len(spline)-1): |
| 421 p2 = spline[i+1] | 433 p2 = spline[i+1] |
| 422 if(round(p1.x, 10) == round(p2.x, 10)): | 434 if(round(p1.x, 10) == round(p2.x, 10)): |
| 423 p2.x += 0.0000000001 | 435 p2.x += 0.0000000001 |
| 424 if(round(p1.y, 10) == round(p2.y, 10)): | 436 if(round(p1.y, 10) == round(p2.y, 10)): |
| 425 p2.y += 0.0000000001 | 437 p2.y += 0.0000000001 |
| 664 @staticmethod | 676 @staticmethod |
| 665 def generate(p, v, nPoints): | 677 def generate(p, v, nPoints): |
| 666 t = Trajectory() | 678 t = Trajectory() |
| 667 p0 = Point(p.x, p.y) | 679 p0 = Point(p.x, p.y) |
| 668 t.addPosition(p0) | 680 t.addPosition(p0) |
| 669 for i in xrange(nPoints-1): | 681 for i in range(nPoints-1): |
| 670 p0 += v | 682 p0 += v |
| 671 t.addPosition(p0) | 683 t.addPosition(p0) |
| 672 return t, Trajectory([[v.x]*nPoints, [v.y]*nPoints]) | 684 return t, Trajectory([[v.x]*nPoints, [v.y]*nPoints]) |
| 673 | 685 |
| 674 @staticmethod | 686 @staticmethod |
| 703 return Trajectory([self.positions[0][i],self.positions[1][i]]) | 715 return Trajectory([self.positions[0][i],self.positions[1][i]]) |
| 704 else: | 716 else: |
| 705 raise TypeError("Invalid argument type.") | 717 raise TypeError("Invalid argument type.") |
| 706 | 718 |
| 707 def __str__(self): | 719 def __str__(self): |
| 708 return ' '.join([self.__getitem__(i).__str__() for i in xrange(self.length())]) | 720 return ' '.join([self.__getitem__(i).__str__() for i in range(self.length())]) |
| 709 | 721 |
| 710 def __repr__(self): | 722 def __repr__(self): |
| 711 return self.__str__() | 723 return self.__str__() |
| 712 | 724 |
| 713 def __iter__(self): | 725 def __iter__(self): |
| 714 self.iterInstantNum = 0 | 726 self.iterInstantNum = 0 |
| 715 return self | 727 return self |
| 716 | 728 |
| 717 def next(self): | 729 def __next__(self): |
| 718 if self.iterInstantNum >= self.length(): | 730 if self.iterInstantNum >= self.length(): |
| 719 raise StopIteration | 731 raise StopIteration |
| 720 else: | 732 else: |
| 721 self.iterInstantNum += 1 | 733 self.iterInstantNum += 1 |
| 722 return self[self.iterInstantNum-1] | 734 return self[self.iterInstantNum-1] |
| 817 return Trajectory([[alpha*x for x in self.getXCoordinates()], | 829 return Trajectory([[alpha*x for x in self.getXCoordinates()], |
| 818 [alpha*y for y in self.getYCoordinates()]]) | 830 [alpha*y for y in self.getYCoordinates()]]) |
| 819 | 831 |
| 820 def differentiate(self, doubleLastPosition = False): | 832 def differentiate(self, doubleLastPosition = False): |
| 821 diff = Trajectory() | 833 diff = Trajectory() |
| 822 for i in xrange(1, self.length()): | 834 for i in range(1, self.length()): |
| 823 diff.addPosition(self[i]-self[i-1]) | 835 diff.addPosition(self[i]-self[i-1]) |
| 824 if doubleLastPosition: | 836 if doubleLastPosition: |
| 825 diff.addPosition(diff[-1]) | 837 diff.addPosition(diff[-1]) |
| 826 return diff | 838 return diff |
| 827 | 839 |
| 854 Can be accessed through getDistance(idx) and getCumulativeDistance(idx)''' | 866 Can be accessed through getDistance(idx) and getCumulativeDistance(idx)''' |
| 855 self.distances = [] | 867 self.distances = [] |
| 856 self.cumulativeDistances = [0.] | 868 self.cumulativeDistances = [0.] |
| 857 p1 = self[0] | 869 p1 = self[0] |
| 858 cumulativeDistance = 0. | 870 cumulativeDistance = 0. |
| 859 for i in xrange(self.length()-1): | 871 for i in range(self.length()-1): |
| 860 p2 = self[i+1] | 872 p2 = self[i+1] |
| 861 self.distances.append(Point.distanceNorm2(p1,p2)) | 873 self.distances.append(Point.distanceNorm2(p1,p2)) |
| 862 cumulativeDistance += self.distances[-1] | 874 cumulativeDistance += self.distances[-1] |
| 863 self.cumulativeDistances.append(cumulativeDistance) | 875 self.cumulativeDistances.append(cumulativeDistance) |
| 864 p1 = p2 | 876 p1 = p2 |
| 921 intersects with the segment of extremities p1 and p2 | 933 intersects with the segment of extremities p1 and p2 |
| 922 Returns an empty list if there is no crossing''' | 934 Returns an empty list if there is no crossing''' |
| 923 indices = [] | 935 indices = [] |
| 924 intersections = [] | 936 intersections = [] |
| 925 | 937 |
| 926 for i in xrange(self.length()-1): | 938 for i in range(self.length()-1): |
| 927 q1=self.__getitem__(i) | 939 q1=self.__getitem__(i) |
| 928 q2=self.__getitem__(i+1) | 940 q2=self.__getitem__(i+1) |
| 929 p = segmentIntersection(q1, q2, p1, p2) | 941 p = segmentIntersection(q1, q2, p1, p2) |
| 930 if p is not None: | 942 if p is not None: |
| 931 if q1.x != q2.x: | 943 if q1.x != q2.x: |
| 943 intersects with the line going through p1 and p2 | 955 intersects with the line going through p1 and p2 |
| 944 Returns an empty list if there is no crossing''' | 956 Returns an empty list if there is no crossing''' |
| 945 indices = [] | 957 indices = [] |
| 946 intersections = [] | 958 intersections = [] |
| 947 | 959 |
| 948 for i in xrange(self.length()-1): | 960 for i in range(self.length()-1): |
| 949 q1=self.__getitem__(i) | 961 q1=self.__getitem__(i) |
| 950 q2=self.__getitem__(i+1) | 962 q2=self.__getitem__(i+1) |
| 951 p = segmentLineIntersection(p1, p2, q1, q2) | 963 p = segmentLineIntersection(p1, p2, q1, q2) |
| 952 if p is not None: | 964 if p is not None: |
| 953 if q1.x != q2.x: | 965 if q1.x != q2.x: |
| 1076 self.lanes[i] = lane | 1088 self.lanes[i] = lane |
| 1077 | 1089 |
| 1078 def differentiate(self, doubleLastPosition = False): | 1090 def differentiate(self, doubleLastPosition = False): |
| 1079 diff = CurvilinearTrajectory() | 1091 diff = CurvilinearTrajectory() |
| 1080 p1 = self[0] | 1092 p1 = self[0] |
| 1081 for i in xrange(1, self.length()): | 1093 for i in range(1, self.length()): |
| 1082 p2 = self[i] | 1094 p2 = self[i] |
| 1083 diff.addPositionSYL(p2[0]-p1[0], p2[1]-p1[1], p1[2]) | 1095 diff.addPositionSYL(p2[0]-p1[0], p2[1]-p1[1], p1[2]) |
| 1084 p1=p2 | 1096 p1=p2 |
| 1085 if doubleLastPosition and self.length() > 1: | 1097 if doubleLastPosition and self.length() > 1: |
| 1086 diff.addPosition(diff[-1]) | 1098 diff.addPosition(diff[-1]) |
| 1090 '''Returns a list of the indices at which the trajectory | 1102 '''Returns a list of the indices at which the trajectory |
| 1091 goes past the curvilinear coordinate S1 | 1103 goes past the curvilinear coordinate S1 |
| 1092 (in provided lane if lane is not None) | 1104 (in provided lane if lane is not None) |
| 1093 Returns an empty list if there is no crossing''' | 1105 Returns an empty list if there is no crossing''' |
| 1094 indices = [] | 1106 indices = [] |
| 1095 for i in xrange(self.length()-1): | 1107 for i in range(self.length()-1): |
| 1096 q1=self.__getitem__(i) | 1108 q1=self.__getitem__(i) |
| 1097 q2=self.__getitem__(i+1) | 1109 q2=self.__getitem__(i+1) |
| 1098 if q1[0] <= S1 < q2[0] and (lane is None or (self.lanes[i] == lane and self.lanes[i+1] == lane)): | 1110 if q1[0] <= S1 < q2[0] and (lane is None or (self.lanes[i] == lane and self.lanes[i+1] == lane)): |
| 1099 indices.append(i+(S1-q1[0])/(q2[0]-q1[0])) | 1111 indices.append(i+(S1-q1[0])/(q2[0]-q1[0])) |
| 1100 return indices | 1112 return indices |
| 1259 self.positions = positions | 1271 self.positions = positions |
| 1260 | 1272 |
| 1261 @staticmethod | 1273 @staticmethod |
| 1262 def concatenate(obj1, obj2, num = None): | 1274 def concatenate(obj1, obj2, num = None): |
| 1263 '''Concatenates two objects supposed to overlap temporally ''' | 1275 '''Concatenates two objects supposed to overlap temporally ''' |
| 1264 if num is None: | 1276 if num is None: |
| 1265 newNum = obj1.getNum() | 1277 newNum = obj1.getNum() |
| 1266 else: | 1278 else: |
| 1267 newNum = num | 1279 newNum = num |
| 1268 commonTimeInterval = obj1.commonTimeInterval(obj2) | 1280 commonTimeInterval = obj1.commonTimeInterval(obj2) |
| 1269 if commonTimeInterval.empty(): | 1281 if commonTimeInterval.empty(): |
| 1270 print('The two objects\' time intervals do not overlap: obj1 {} and obj2 {}'.format(obj1.getTimeInterval(), obj2.getTimeInterval())) | 1282 print('The two objects\' time intervals do not overlap: obj1 {} and obj2 {}'.format(obj1.getTimeInterval(), obj2.getTimeInterval())) |
| 1271 emptyInterval = TimeInterval(min(obj1.getLastInstant(),obj2.getLastInstant()) , max(obj1.getFirstInstant(),obj2.getFirstInstant())) | 1283 emptyInterval = TimeInterval(min(obj1.getLastInstant(),obj2.getLastInstant()) , max(obj1.getFirstInstant(),obj2.getFirstInstant())) |
| 1272 positions = Trajectory() | 1284 positions = Trajectory() |
| 1287 py+=vitessey | 1299 py+=vitessey |
| 1288 | 1300 |
| 1289 newObject = MovingObject(newNum, emptyInterval, positions, velocities, userType = obj1.getUserType()) | 1301 newObject = MovingObject(newNum, emptyInterval, positions, velocities, userType = obj1.getUserType()) |
| 1290 newObject.features = [MovingObject(newNum, emptyInterval, positions, velocities, userType = obj1.getUserType())] #In case there is features to add when we recursively call concatenate | 1302 newObject.features = [MovingObject(newNum, emptyInterval, positions, velocities, userType = obj1.getUserType())] #In case there is features to add when we recursively call concatenate |
| 1291 return MovingObject.concatenate(MovingObject.concatenate(obj1, newObject),obj2) | 1303 return MovingObject.concatenate(MovingObject.concatenate(obj1, newObject),obj2) |
| 1292 | 1304 |
| 1293 | |
| 1294 else: | 1305 else: |
| 1295 newTimeInterval = TimeInterval.union(obj1.getTimeInterval(), obj2.getTimeInterval()) | 1306 newTimeInterval = TimeInterval.union(obj1.getTimeInterval(), obj2.getTimeInterval()) |
| 1296 # positions | 1307 # positions |
| 1297 positions = Trajectory() | 1308 positions = Trajectory() |
| 1298 for t in newTimeInterval: | 1309 for t in newTimeInterval: |
| 1422 coords.append(NaN) | 1433 coords.append(NaN) |
| 1423 plot(instants, coords, options, **kwargs) | 1434 plot(instants, coords, options, **kwargs) |
| 1424 if withOrigin and len(instants)>0: | 1435 if withOrigin and len(instants)>0: |
| 1425 plot([instants[0]], [coords[0]], 'ro', **kwargs) | 1436 plot([instants[0]], [coords[0]], 'ro', **kwargs) |
| 1426 else: | 1437 else: |
| 1427 print('Object {} has no curvilinear positions'.format(self.getNum())) | 1438 print('Object {} has no curvilinear positions'.format(self.getNum())) |
| 1428 | 1439 |
| 1429 def setUserType(self, userType): | 1440 def setUserType(self, userType): |
| 1430 self.userType = userType | 1441 self.userType = userType |
| 1431 | 1442 |
| 1432 def setFeatures(self, features, featuresOrdered = False): | 1443 def setFeatures(self, features, featuresOrdered = False): |
| 1531 def play(self, videoFilename, homography = None, undistort = False, intrinsicCameraMatrix = None, distortionCoefficients = None, undistortedImageMultiplication = 1.): | 1542 def play(self, videoFilename, homography = None, undistort = False, intrinsicCameraMatrix = None, distortionCoefficients = None, undistortedImageMultiplication = 1.): |
| 1532 cvutils.displayTrajectories(videoFilename, [self], homography = homography, firstFrameNum = self.getFirstInstant(), lastFrameNumArg = self.getLastInstant(), undistort = undistort, intrinsicCameraMatrix = intrinsicCameraMatrix, distortionCoefficients = distortionCoefficients, undistortedImageMultiplication = undistortedImageMultiplication) | 1543 cvutils.displayTrajectories(videoFilename, [self], homography = homography, firstFrameNum = self.getFirstInstant(), lastFrameNumArg = self.getLastInstant(), undistort = undistort, intrinsicCameraMatrix = intrinsicCameraMatrix, distortionCoefficients = distortionCoefficients, undistortedImageMultiplication = undistortedImageMultiplication) |
| 1533 | 1544 |
| 1534 def speedDiagnostics(self, framerate = 1., display = False, nInstantsIgnoredAtEnds=0): | 1545 def speedDiagnostics(self, framerate = 1., display = False, nInstantsIgnoredAtEnds=0): |
| 1535 speeds = framerate*self.getSpeeds(nInstantsIgnoredAtEnds) | 1546 speeds = framerate*self.getSpeeds(nInstantsIgnoredAtEnds) |
| 1536 coef = utils.linearRegression(range(len(speeds)), speeds) | 1547 coef = utils.linearRegression(list(range(len(speeds))), speeds) |
| 1537 print('min/5th perc speed: {} / {}\nspeed diff: {}\nspeed stdev: {}\nregression: {}'.format(min(speeds), scoreatpercentile(speeds, 5), speeds[-2]-speeds[1], std(speeds), coef[0])) | 1548 print('min/5th perc speed: {} / {}\nspeed diff: {}\nspeed stdev: {}\nregression: {}'.format(min(speeds), scoreatpercentile(speeds, 5), speeds[-2]-speeds[1], std(speeds), coef[0])) |
| 1538 if display: | 1549 if display: |
| 1539 from matplotlib.pyplot import figure, axis | 1550 from matplotlib.pyplot import figure, axis |
| 1540 figure(1) | 1551 figure(1) |
| 1541 self.plot() | 1552 self.plot() |
| 1666 ''' | 1677 ''' |
| 1667 | 1678 |
| 1668 self.curvilinearPositions = CurvilinearTrajectory() | 1679 self.curvilinearPositions = CurvilinearTrajectory() |
| 1669 | 1680 |
| 1670 #For each point | 1681 #For each point |
| 1671 for i in xrange(int(self.length())): | 1682 for i in range(int(self.length())): |
| 1672 result = getSYfromXY(self.getPositionAt(i), alignments) | 1683 result = getSYfromXY(self.getPositionAt(i), alignments) |
| 1673 | 1684 |
| 1674 # Error handling | 1685 # Error handling |
| 1675 if(result is None): | 1686 if(result is None): |
| 1676 print('Warning: trajectory {} at point {} {} has alignment errors (spline snapping)\nCurvilinear trajectory could not be computed'.format(self.getNum(), i, self.getPositionAt(i))) | 1687 print('Warning: trajectory {} at point {} {} has alignment errors (spline snapping)\nCurvilinear trajectory could not be computed'.format(self.getNum(), i, self.getPositionAt(i))) |
| 1682 #Run through objects looking for outlier point | 1693 #Run through objects looking for outlier point |
| 1683 smoothed_lanes = utils.cat_mvgavg(self.curvilinearPositions.getLanes(),ln_mv_av_win) | 1694 smoothed_lanes = utils.cat_mvgavg(self.curvilinearPositions.getLanes(),ln_mv_av_win) |
| 1684 ## Recalculate projected point to new lane | 1695 ## Recalculate projected point to new lane |
| 1685 lanes = self.curvilinearPositions.getLanes() | 1696 lanes = self.curvilinearPositions.getLanes() |
| 1686 if(lanes != smoothed_lanes): | 1697 if(lanes != smoothed_lanes): |
| 1687 for i in xrange(len(lanes)): | 1698 for i in range(len(lanes)): |
| 1688 if(lanes[i] != smoothed_lanes[i]): | 1699 if(lanes[i] != smoothed_lanes[i]): |
| 1689 result = getSYfromXY(self.getPositionAt(i),[alignments[smoothed_lanes[i]]]) | 1700 result = getSYfromXY(self.getPositionAt(i),[alignments[smoothed_lanes[i]]]) |
| 1690 | 1701 |
| 1691 # Error handling | 1702 # Error handling |
| 1692 if(result is None): | 1703 if(result is None): |
| 1706 if nFeatures == 0: | 1717 if nFeatures == 0: |
| 1707 print('Empty object features\nCannot compute smooth trajectory') | 1718 print('Empty object features\nCannot compute smooth trajectory') |
| 1708 else: | 1719 else: |
| 1709 # compute the relative position vectors | 1720 # compute the relative position vectors |
| 1710 relativePositions = {} # relativePositions[(i,j)] is the position of j relative to i | 1721 relativePositions = {} # relativePositions[(i,j)] is the position of j relative to i |
| 1711 for i in xrange(nFeatures): | 1722 for i in range(nFeatures): |
| 1712 for j in xrange(i): | 1723 for j in range(i): |
| 1713 fi = self.features[i] | 1724 fi = self.features[i] |
| 1714 fj = self.features[j] | 1725 fj = self.features[j] |
| 1715 inter = fi.commonTimeInterval(fj) | 1726 inter = fi.commonTimeInterval(fj) |
| 1716 if inter.length() >= minCommonIntervalLength: | 1727 if inter.length() >= minCommonIntervalLength: |
| 1717 xi = array(fi.getXCoordinates()[inter.first-fi.getFirstInstant():int(fi.length())-(fi.getLastInstant()-inter.last)]) | 1728 xi = array(fi.getXCoordinates()[inter.first-fi.getFirstInstant():int(fi.length())-(fi.getLastInstant()-inter.last)]) |
| 1960 gtMatches = {a.getNum():{} for a in annotations} | 1971 gtMatches = {a.getNum():{} for a in annotations} |
| 1961 toMatches = {o.getNum():{} for o in objects} | 1972 toMatches = {o.getNum():{} for o in objects} |
| 1962 else: | 1973 else: |
| 1963 gtMatches = None | 1974 gtMatches = None |
| 1964 toMatches = None | 1975 toMatches = None |
| 1965 for t in xrange(firstInstant, lastInstant+1): | 1976 for t in range(firstInstant, lastInstant+1): |
| 1966 previousMatches = matches.copy() | 1977 previousMatches = matches.copy() |
| 1967 # go through currently matched GT-TO and check if they are still matched withing matchingDistance | 1978 # go through currently matched GT-TO and check if they are still matched withing matchingDistance |
| 1968 toDelete = [] | 1979 toDelete = [] |
| 1969 for a in matches: | 1980 for a in matches: |
| 1970 if a.existsAtInstant(t) and matches[a].existsAtInstant(t): | 1981 if a.existsAtInstant(t) and matches[a].existsAtInstant(t): |
| 1977 toDelete.append(a) | 1988 toDelete.append(a) |
| 1978 for a in toDelete: | 1989 for a in toDelete: |
| 1979 del matches[a] | 1990 del matches[a] |
| 1980 | 1991 |
| 1981 # match all unmatched GT-TO | 1992 # match all unmatched GT-TO |
| 1982 matchedGTs = matches.keys() | 1993 matchedGTs = list(matches.keys()) |
| 1983 matchedTOs = matches.values() | 1994 matchedTOs = list(matches.values()) |
| 1984 costs = [] | 1995 costs = [] |
| 1985 unmatchedGTs = [a for a in annotations if a.existsAtInstant(t) and a not in matchedGTs] | 1996 unmatchedGTs = [a for a in annotations if a.existsAtInstant(t) and a not in matchedGTs] |
| 1986 unmatchedTOs = [o for o in objects if o.existsAtInstant(t) and o not in matchedTOs] | 1997 unmatchedTOs = [o for o in objects if o.existsAtInstant(t) and o not in matchedTOs] |
| 1987 nGTs = len(matchedGTs)+len(unmatchedGTs) | 1998 nGTs = len(matchedGTs)+len(unmatchedGTs) |
| 1988 nTOs = len(matchedTOs)+len(unmatchedTOs) | 1999 nTOs = len(matchedTOs)+len(unmatchedTOs) |
| 1994 for k,v in newMatches: | 2005 for k,v in newMatches: |
| 1995 if costs[k][v] < matchingDistance: | 2006 if costs[k][v] < matchingDistance: |
| 1996 matches[unmatchedGTs[k]]=unmatchedTOs[v] | 2007 matches[unmatchedGTs[k]]=unmatchedTOs[v] |
| 1997 dist += costs[k][v] | 2008 dist += costs[k][v] |
| 1998 if debug: | 2009 if debug: |
| 1999 print('{} '.format(t)+', '.join(['{} {}'.format(k.getNum(), v.getNum()) for k,v in matches.iteritems()])) | 2010 print('{} '.format(t)+', '.join(['{} {}'.format(k.getNum(), v.getNum()) for k,v in matches.items()])) |
| 2000 if returnMatches: | 2011 if returnMatches: |
| 2001 for a,o in matches.iteritems(): | 2012 for a,o in matches.items(): |
| 2002 gtMatches[a.getNum()][t] = o.getNum() | 2013 gtMatches[a.getNum()][t] = o.getNum() |
| 2003 toMatches[o.getNum()][t] = a.getNum() | 2014 toMatches[o.getNum()][t] = a.getNum() |
| 2004 | 2015 |
| 2005 # compute metrics elements | 2016 # compute metrics elements |
| 2006 ct += len(matches) | 2017 ct += len(matches) |
| 2012 mismatches = [] | 2023 mismatches = [] |
| 2013 for a in matches: | 2024 for a in matches: |
| 2014 if a in previousMatches: | 2025 if a in previousMatches: |
| 2015 if matches[a] != previousMatches[a]: | 2026 if matches[a] != previousMatches[a]: |
| 2016 mismatches.append(a) | 2027 mismatches.append(a) |
| 2017 elif matches[a] in previousMatches.values(): | 2028 elif matches[a] in list(previousMatches.values()): |
| 2018 mismatches.append(matches[a]) | 2029 mismatches.append(matches[a]) |
| 2019 for a in previousMatches: | 2030 for a in previousMatches: |
| 2020 if a not in matches and previousMatches[a] in matches.values(): | 2031 if a not in matches and previousMatches[a] in list(matches.values()): |
| 2021 mismatches.append(previousMatches[a]) | 2032 mismatches.append(previousMatches[a]) |
| 2022 if debug: | 2033 if debug: |
| 2023 for mm in set(mismatches): | 2034 for mm in set(mismatches): |
| 2024 print('{} {}'.format(type(mm), mm.getNum())) | 2035 print('{} {}'.format(type(mm), mm.getNum())) |
| 2025 # some object mismatches may appear twice | 2036 # some object mismatches may appear twice |
