Mercurial > hg > nsaunier > traffic-intelligence
diff python/metadata.py @ 824:28526917a583
merged
| author | Nicolas Saunier <nicolas.saunier@polymtl.ca> |
|---|---|
| date | Mon, 27 Jun 2016 16:19:34 -0400 |
| parents | 26daf35180ad |
| children | 6e4357e9116d |
line wrap: on
line diff
--- a/python/metadata.py Mon Jun 27 16:19:06 2016 -0400 +++ b/python/metadata.py Mon Jun 27 16:19:34 2016 -0400 @@ -1,13 +1,14 @@ # from moving import Point -from datetime import datetime +from datetime import datetime, timedelta from os import path +from math import floor -from sqlalchemy import create_engine, Column, Integer, Float, DateTime, String, ForeignKey +from sqlalchemy import orm, create_engine, Column, Integer, Float, DateTime, String, ForeignKey, Boolean, Interval from sqlalchemy.orm import relationship, backref, sessionmaker from sqlalchemy.ext.declarative import declarative_base -from utils import datetimeFormat +from utils import datetimeFormat, removeExtension Base = declarative_base() @@ -20,14 +21,16 @@ ycoordinate = Column(Float) mapImageFilename = Column(String) # path to filename, relative to site name, ie sitename/mapImageFilename nUnitsPerPixel = Column(Float) # number of units of distance per pixel in map image + worldDistanceUnit = Column(String, default = 'm') # make sure it is default in the database - def __init__(self, name, description = "", xcoordinate = None, ycoordinate = None, mapImageFilename = None, nUnitsPerPixel = 1.): + def __init__(self, name, description = "", xcoordinate = None, ycoordinate = None, mapImageFilename = None, nUnitsPerPixel = 1., worldDistanceUnit = 'm'): self.name = name self.description = description self.xcoordinate = xcoordinate self.ycoordinate = ycoordinate self.mapImageFilename = mapImageFilename self.nUnitsPerPixel = nUnitsPerPixel + self.worldDistanceUnit = worldDistanceUnit def getFilename(self): return self.name @@ -53,23 +56,77 @@ self.description = description self.site = site +class CameraType(Base): + ''' Represents parameters of the specific camera used. + + Taken and adapted from tvalib''' + __tablename__ = 'camera_types' + idx = Column(Integer, primary_key=True) + name = Column(String) + resX = Column(Integer) + resY = Column(Integer) + frameRate = Column(Float) + frameRateTimeUnit = Column(String, default = 's') + undistort = Column(Boolean) + intrinsicCameraMatrixStr = Column(String) + distortionCoefficientsStr = Column(String) + undistortedImageMultiplication = Column(Float) + + def __init__(self, name, resX, resY, frameRate, frameRateTimeUnit = 's', trackingConfigurationFilename = None, undistort = None, intrinsicCameraMatrix = None, distortionCoefficients = None, undistortedImageMultiplication = None): + self.name = name + self.resX = resX + self.resY = resY + self.frameRate = frameRate + self.frameRateTimeUnit = frameRateTimeUnit + self.undistort = False + + if trackingConfigurationFilename is not None: + from storage import ProcessParameters + params = ProcessParameters(trackingConfigurationFilename) + if params.undistort: + self.undistort = params.undistort + self.intrinsicCameraMatrix = params.intrinsicCameraMatrix + self.distortionCoefficients = params.distortionCoefficients + self.undistortedImageMultiplication = params.undistortedImageMultiplication + elif undistort is not None: + self.undistort = undistort + self.intrinsicCameraMatrix = intrinsicCameraMatrix + self.distortionCoefficients = distortionCoefficients + self.undistortedImageMultiplication = undistortedImageMultiplication + + # populate the db + if hasattr(self, 'intrinsicCameraMatrix') and self.intrinsicCameraMatrix is not None\ + and hasattr(self, 'distortionCoefficients') and self.distortionCoefficients is not None: + self.intrinsicCameraMatrixStr = ' '.join('{}'.format(x) for x in self.intrinsicCameraMatrix.flatten('C')) + self.distortionCoefficientsStr = ' '.join('{}'.format(x)for x in self.distortionCoefficients) + + @orm.reconstructor + def initOnLoad(self): + from numpy import array + if len(self.intrinsicCameraMatrixStr) > 0: + self.intrinsicCameraMatrix = array([float(x) for x in self.intrinsicCameraMatrixStr.split(" ")]).reshape(3,3) + if len(self.distortionCoefficientsStr) > 0: + self.distortionCoefficients = [float(x) for x in self.distortionCoefficientsStr.split(" ")] + class CameraView(Base): __tablename__ = 'camera_views' idx = Column(Integer, primary_key=True) - frameRate = Column(Float) + description = Column(String) homographyFilename = Column(String) # path to homograph filename, relative to the site name - cameraCalibrationFilename = Column(String) # path to full camera calibration, relative to the site name siteIdx = Column(Integer, ForeignKey('sites.idx')) + cameraTypeIdx = Column(Integer, ForeignKey('camera_types.idx')) homographyDistanceUnit = Column(String, default = 'm') # make sure it is default in the database - configurationFilename = Column(String) # path to configuration .cfg file, relative to site name + trackingConfigurationFilename = Column(String) # path to configuration .cfg file, relative to site name - site = relationship("Site", backref=backref('camera_views', order_by = idx)) + site = relationship("Site", backref=backref('sites', order_by = idx)) + cameraType = relationship('CameraType', backref=backref('camera_views', order_by = idx)) - def __init__(self, frameRate, homographyFilename, cameraCalibrationFilename, site, configurationFilename): - self.frameRate = frameRate + def __init__(self, description, homographyFilename, site, cameraType, trackingConfigurationFilename): + self.description = description self.homographyFilename = homographyFilename self.site = site - self.configurationFilename = configurationFilename + self.cameraType = cameraType + self.trackingConfigurationFilename = trackingConfigurationFilename def getHomographyFilename(self, relativeToSiteFilename = True): if relativeToSiteFilename: @@ -77,6 +134,15 @@ else: return self.homographyFilename + def getTrackingConfigurationFilename(self, relativeToSiteFilename = True): + if relativeToSiteFilename: + return self.site.getFilename()+path.sep+self.trackingConfigurationFilename + else: + return self.trackingConfigurationFilename + + def getTrackingParameters(self): + return ProcessParameters(getTrackingConfigurationFilename()) + class Alignment(Base): __tablename__ = 'alignments' idx = Column(Integer, primary_key=True) @@ -107,23 +173,24 @@ idx = Column(Integer, primary_key=True) name = Column(String) # path relative to the the site name startTime = Column(DateTime) - duration = Column(Float) # video sequence duration - durationUnit = Column(String, default = 's') + duration = Column(Interval) # video sequence duration + databaseFilename = Column(String) # path relative to the the site name siteIdx = Column(Integer, ForeignKey('sites.idx')) cameraViewIdx = Column(Integer, ForeignKey('camera_views.idx')) - configurationFilename = Column(String) site = relationship("Site", backref=backref('video_sequences', order_by = idx)) cameraView = relationship("CameraView", backref=backref('video_sequences', order_by = idx)) - def __init__(self, name, startTime, duration, site, cameraView, configurationFilename = None): - 'startTime is passed as string in utils.datetimeFormat, eg 2011-06-22 10:00:39' + def __init__(self, name, startTime, duration, site, cameraView, databaseFilename = None): + '''startTime is passed as string in utils.datetimeFormat, eg 2011-06-22 10:00:39 + duration is a timedelta object''' self.name = name self.startTime = datetime.strptime(startTime, datetimeFormat) self.duration = duration self.site = site self.cameraView = cameraView - self.configurationFilename = configurationFilename + if databaseFilename is None and len(self.name) > 0: + self.databaseFilename = removeExtension(self.name)+'.sqlite' def getVideoSequenceFilename(self, relativeToSiteFilename = True): if relativeToSiteFilename: @@ -131,8 +198,16 @@ else: return self.name - #def getConfigurationFilename(self): - #'returns the local configuration filename, or the one of the camera view otherwise' + def containsInstant(self, instant): + 'instant is a datetime' + return self.startTime <= instant and self.startTime+self.duration + + def getFrameNum(self, instant): + 'Warning, there is no check of correct time units' + if self.containsInstant(instant): + return int(floor((instant-self.startTime).seconds*self.cameraView.cameraType.frameRate)) + else: + return None # add class for Analysis: foreign key VideoSequenceId, dataFilename, configFilename (get the one from camera view by default), mask? (no, can be referenced in the tracking cfg file)
