Mercurial > hg > nsaunier > traffic-intelligence
comparison python/storage.py @ 509:935430b1d408
corrected mask bug in feature tracking, updated display-trajectories to display on undistorted image
| author | Nicolas Saunier <nicolas.saunier@polymtl.ca> |
|---|---|
| date | Fri, 23 May 2014 16:27:26 -0400 |
| parents | 343cfd185ca6 |
| children | 1ba618fb0f70 |
comparison
equal
deleted
inserted
replaced
| 508:6f7fa0093162 | 509:935430b1d408 |
|---|---|
| 6 | 6 |
| 7 import sqlite3, logging | 7 import sqlite3, logging |
| 8 | 8 |
| 9 __metaclass__ = type | 9 __metaclass__ = type |
| 10 | 10 |
| 11 | |
| 12 commentChar = '#' | |
| 13 | |
| 14 delimiterChar = '%'; | |
| 11 | 15 |
| 12 ngsimUserTypes = {'twowheels':1, | 16 ngsimUserTypes = {'twowheels':1, |
| 13 'car':2, | 17 'car':2, |
| 14 'truck':3} | 18 'truck':3} |
| 15 | 19 |
| 350 | 354 |
| 351 ######################### | 355 ######################### |
| 352 # txt files | 356 # txt files |
| 353 ######################### | 357 ######################### |
| 354 | 358 |
| 359 def openCheck(filename, option = 'r', quit = False): | |
| 360 '''Open file filename in read mode by default | |
| 361 and checks it is open''' | |
| 362 try: | |
| 363 return open(filename, option) | |
| 364 except IOError: | |
| 365 print 'File %s could not be opened.' % filename | |
| 366 if quit: | |
| 367 from sys import exit | |
| 368 exit() | |
| 369 return None | |
| 370 | |
| 371 def readline(f, commentChar = commentChar): | |
| 372 '''Modified readline function to skip comments.''' | |
| 373 s = f.readline() | |
| 374 while (len(s) > 0) and s.startswith(commentChar): | |
| 375 s = f.readline() | |
| 376 return s.strip() | |
| 377 | |
| 378 def getLines(f, commentChar = commentChar): | |
| 379 '''Gets a complete entry (all the lines) in between delimiterChar.''' | |
| 380 dataStrings = [] | |
| 381 s = readline(f, commentChar) | |
| 382 while len(s) > 0: | |
| 383 dataStrings += [s.strip()] | |
| 384 s = readline(f, commentChar) | |
| 385 return dataStrings | |
| 386 | |
| 387 def writeList(filename, l): | |
| 388 f = utils.openCheck(filename, 'w') | |
| 389 for x in l: | |
| 390 f.write('{}\n'.format(x)) | |
| 391 f.close() | |
| 392 | |
| 393 def loadListStrings(filename, commentChar = commentChar): | |
| 394 f = utils.openCheck(filename, 'r') | |
| 395 result = getLines(f, commentChar) | |
| 396 f.close() | |
| 397 return result | |
| 398 | |
| 399 def getValuesFromINIFile(filename, option, delimiterChar = '=', commentChar = commentChar): | |
| 400 values = [] | |
| 401 for l in loadListStrings(filename, commentChar): | |
| 402 if l.startswith(option): | |
| 403 values.append(l.split(delimiterChar)[1].strip()) | |
| 404 return values | |
| 405 | |
| 406 class FakeSecHead(object): | |
| 407 '''Add fake section header [asection] | |
| 408 | |
| 409 from http://stackoverflow.com/questions/2819696/parsing-properties-file-in-python/2819788#2819788 | |
| 410 use read_file in Python 3.2+ | |
| 411 ''' | |
| 412 def __init__(self, fp): | |
| 413 self.fp = fp | |
| 414 self.sechead = '[main]\n' | |
| 415 | |
| 416 def readline(self): | |
| 417 if self.sechead: | |
| 418 try: return self.sechead | |
| 419 finally: self.sechead = None | |
| 420 else: return self.fp.readline() | |
| 421 | |
| 355 def loadTrajectoriesFromNgsimFile(filename, nObjects = -1, sequenceNum = -1): | 422 def loadTrajectoriesFromNgsimFile(filename, nObjects = -1, sequenceNum = -1): |
| 356 '''Reads data from the trajectory data provided by NGSIM project | 423 '''Reads data from the trajectory data provided by NGSIM project |
| 357 and returns the list of Feature objects''' | 424 and returns the list of Feature objects''' |
| 358 objects = [] | 425 objects = [] |
| 359 | 426 |
| 452 f = utils.openCheck(filename, 'w') | 519 f = utils.openCheck(filename, 'w') |
| 453 for i,obj in enumerate(objects): | 520 for i,obj in enumerate(objects): |
| 454 writePositionsToCsv(f, obj) | 521 writePositionsToCsv(f, obj) |
| 455 f.close() | 522 f.close() |
| 456 | 523 |
| 457 def writeList(filename, l): | 524 |
| 458 f = utils.openCheck(filename, 'w') | 525 ######################### |
| 459 for x in l: | 526 # Utils to read .ini type text files for configuration, meta data... |
| 460 f.write('{}\n'.format(x)) | 527 ######################### |
| 461 f.close() | 528 |
| 462 | 529 class TrackingParameters: |
| 463 def loadListStrings(filename): | 530 '''Class for tracking and safety parameters |
| 464 f = utils.openCheck(filename, 'r') | 531 |
| 465 result = [l.strip() for l in f] | 532 Note: framerate is already taken into account''' |
| 466 f.close() | 533 |
| 467 return result | 534 def loadConfigFile(self, filename): |
| 468 | 535 from ConfigParser import ConfigParser |
| 536 from numpy import loadtxt | |
| 537 from os import path | |
| 538 | |
| 539 config = ConfigParser() | |
| 540 config.readfp(FakeSecHead(openCheck(filename))) | |
| 541 self.sectionHeader = config.sections()[0] | |
| 542 self.videoFilename = config.get(self.sectionHeader, 'video-filename') | |
| 543 self.databaseFilename = config.get(self.sectionHeader, 'database-filename') | |
| 544 self.homographyFilename = config.get(self.sectionHeader, 'homography-filename') | |
| 545 if (path.exists(self.homographyFilename)): | |
| 546 self.homography = loadtxt(self.homographyFilename) | |
| 547 else: | |
| 548 self.homography = None | |
| 549 self.intrinsicCameraFilename = config.get(self.sectionHeader, 'intrinsic-camera-filename') | |
| 550 if (path.exists(self.intrinsicCameraFilename)): | |
| 551 self.intrinsicCameraMatrix = loadtxt(self.intrinsicCameraFilename) | |
| 552 else: | |
| 553 self.intrinsicCameraMatrix = None | |
| 554 distortionCoefficients = getValuesFromINIFile(filename, 'distortion-coefficients', '=') | |
| 555 self.distortionCoefficients = [float(x) for x in distortionCoefficients] | |
| 556 self.undistortedImageMultiplication = config.getfloat(self.sectionHeader, 'undistorted-size-multiplication') | |
| 557 self.undistort = config.getboolean(self.sectionHeader, 'undistort') | |
| 558 self.firstFrameNum = config.getint(self.sectionHeader, 'frame1') | |
| 559 self.videoFrameRate = config.getfloat(self.sectionHeader, 'video-fps') | |
| 560 | |
| 561 self.maxPredictedSpeed = config.getfloat(self.sectionHeader, 'max-predicted-speed')/3.6/self.videoFrameRate | |
| 562 self.predictionTimeHorizon = config.getfloat(self.sectionHeader, 'prediction-time-horizon')*self.videoFrameRate | |
| 563 self.collisionDistance = config.getfloat(self.sectionHeader, 'collision-distance') | |
| 564 self.crossingZones = config.getboolean(self.sectionHeader, 'crossing-zones') | |
| 565 self.predictionMethod = config.get(self.sectionHeader, 'prediction-method') | |
| 566 self.nPredictedTrajectories = config.getint(self.sectionHeader, 'npredicted-trajectories') | |
| 567 self.maxNormalAcceleration = config.getfloat(self.sectionHeader, 'max-normal-acceleration')/self.videoFrameRate**2 | |
| 568 self.maxNormalSteering = config.getfloat(self.sectionHeader, 'max-normal-steering')/self.videoFrameRate | |
| 569 self.minExtremeAcceleration = config.getfloat(self.sectionHeader, 'min-extreme-acceleration')/self.videoFrameRate**2 | |
| 570 self.maxExtremeAcceleration = config.getfloat(self.sectionHeader, 'max-extreme-acceleration')/self.videoFrameRate**2 | |
| 571 self.maxExtremeSteering = config.getfloat(self.sectionHeader, 'max-extreme-steering')/self.videoFrameRate | |
| 572 self.useFeaturesForPrediction = config.getboolean(self.sectionHeader, 'use-features-prediction') | |
| 573 | |
| 574 def __init__(self, filename = None): | |
| 575 if filename != None: | |
| 576 self.loadConfigFile(filename) | |
| 577 | |
| 578 class SceneParameters: | |
| 579 def __init__(self, config, sectionName): | |
| 580 from ConfigParser import NoOptionError | |
| 581 from ast import literal_eval | |
| 582 try: | |
| 583 self.sitename = config.get(sectionName, 'sitename') | |
| 584 self.databaseFilename = config.get(sectionName, 'data-filename') | |
| 585 self.homographyFilename = config.get(sectionName, 'homography-filename') | |
| 586 self.calibrationFilename = config.get(sectionName, 'calibration-filename') | |
| 587 self.videoFilename = config.get(sectionName, 'video-filename') | |
| 588 self.frameRate = config.getfloat(sectionName, 'framerate') | |
| 589 self.date = datetime.strptime(config.get(sectionName, 'date'), datetimeFormat) # 2011-06-22 11:00:39 | |
| 590 self.translation = literal_eval(config.get(sectionName, 'translation')) # = [0.0, 0.0] | |
| 591 self.rotation = config.getfloat(sectionName, 'rotation') | |
| 592 self.duration = config.getint(sectionName, 'duration') | |
| 593 except NoOptionError as e: | |
| 594 print(e) | |
| 595 print('Not a section for scene meta-data') | |
| 596 | |
| 597 @staticmethod | |
| 598 def loadConfigFile(filename): | |
| 599 from ConfigParser import ConfigParser | |
| 600 config = ConfigParser() | |
| 601 config.readfp(openCheck(filename)) | |
| 602 configDict = dict() | |
| 603 for sectionName in config.sections(): | |
| 604 configDict[sectionName] = SceneParameters(config, sectionName) | |
| 605 return configDict | |
| 606 | |
| 469 | 607 |
| 470 if __name__ == "__main__": | 608 if __name__ == "__main__": |
| 471 import doctest | 609 import doctest |
| 472 import unittest | 610 import unittest |
| 473 suite = doctest.DocFileSuite('tests/storage.txt') | 611 suite = doctest.DocFileSuite('tests/storage.txt') |
