Mercurial Hosting > traffic-intelligence
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)) |