Mercurial > hg > nsaunier > traffic-intelligence
comparison 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 |
comparison
equal
deleted
inserted
replaced
| 823:f6790357f53b | 824:28526917a583 |
|---|---|
| 1 # from moving import Point | 1 # from moving import Point |
| 2 | 2 |
| 3 from datetime import datetime | 3 from datetime import datetime, timedelta |
| 4 from os import path | 4 from os import path |
| 5 | 5 from math import floor |
| 6 from sqlalchemy import create_engine, Column, Integer, Float, DateTime, String, ForeignKey | 6 |
| 7 from sqlalchemy import orm, create_engine, Column, Integer, Float, DateTime, String, ForeignKey, Boolean, Interval | |
| 7 from sqlalchemy.orm import relationship, backref, sessionmaker | 8 from sqlalchemy.orm import relationship, backref, sessionmaker |
| 8 from sqlalchemy.ext.declarative import declarative_base | 9 from sqlalchemy.ext.declarative import declarative_base |
| 9 | 10 |
| 10 from utils import datetimeFormat | 11 from utils import datetimeFormat, removeExtension |
| 11 | 12 |
| 12 Base = declarative_base() | 13 Base = declarative_base() |
| 13 | 14 |
| 14 class Site(Base): | 15 class Site(Base): |
| 15 __tablename__ = 'sites' | 16 __tablename__ = 'sites' |
| 18 description = Column(String) # longer names, eg intersection of road1 and road2 | 19 description = Column(String) # longer names, eg intersection of road1 and road2 |
| 19 xcoordinate = Column(Float) # ideally moving.Point, but needs to be | 20 xcoordinate = Column(Float) # ideally moving.Point, but needs to be |
| 20 ycoordinate = Column(Float) | 21 ycoordinate = Column(Float) |
| 21 mapImageFilename = Column(String) # path to filename, relative to site name, ie sitename/mapImageFilename | 22 mapImageFilename = Column(String) # path to filename, relative to site name, ie sitename/mapImageFilename |
| 22 nUnitsPerPixel = Column(Float) # number of units of distance per pixel in map image | 23 nUnitsPerPixel = Column(Float) # number of units of distance per pixel in map image |
| 23 | 24 worldDistanceUnit = Column(String, default = 'm') # make sure it is default in the database |
| 24 def __init__(self, name, description = "", xcoordinate = None, ycoordinate = None, mapImageFilename = None, nUnitsPerPixel = 1.): | 25 |
| 26 def __init__(self, name, description = "", xcoordinate = None, ycoordinate = None, mapImageFilename = None, nUnitsPerPixel = 1., worldDistanceUnit = 'm'): | |
| 25 self.name = name | 27 self.name = name |
| 26 self.description = description | 28 self.description = description |
| 27 self.xcoordinate = xcoordinate | 29 self.xcoordinate = xcoordinate |
| 28 self.ycoordinate = ycoordinate | 30 self.ycoordinate = ycoordinate |
| 29 self.mapImageFilename = mapImageFilename | 31 self.mapImageFilename = mapImageFilename |
| 30 self.nUnitsPerPixel = nUnitsPerPixel | 32 self.nUnitsPerPixel = nUnitsPerPixel |
| 33 self.worldDistanceUnit = worldDistanceUnit | |
| 31 | 34 |
| 32 def getFilename(self): | 35 def getFilename(self): |
| 33 return self.name | 36 return self.name |
| 34 | 37 |
| 35 class EnvironementalFactors(Base): | 38 class EnvironementalFactors(Base): |
| 51 self.startTime = datetime.strptime(startTime, datetimeFormat) | 54 self.startTime = datetime.strptime(startTime, datetimeFormat) |
| 52 self.endTime = datetime.strptime(endTime, datetimeFormat) | 55 self.endTime = datetime.strptime(endTime, datetimeFormat) |
| 53 self.description = description | 56 self.description = description |
| 54 self.site = site | 57 self.site = site |
| 55 | 58 |
| 59 class CameraType(Base): | |
| 60 ''' Represents parameters of the specific camera used. | |
| 61 | |
| 62 Taken and adapted from tvalib''' | |
| 63 __tablename__ = 'camera_types' | |
| 64 idx = Column(Integer, primary_key=True) | |
| 65 name = Column(String) | |
| 66 resX = Column(Integer) | |
| 67 resY = Column(Integer) | |
| 68 frameRate = Column(Float) | |
| 69 frameRateTimeUnit = Column(String, default = 's') | |
| 70 undistort = Column(Boolean) | |
| 71 intrinsicCameraMatrixStr = Column(String) | |
| 72 distortionCoefficientsStr = Column(String) | |
| 73 undistortedImageMultiplication = Column(Float) | |
| 74 | |
| 75 def __init__(self, name, resX, resY, frameRate, frameRateTimeUnit = 's', trackingConfigurationFilename = None, undistort = None, intrinsicCameraMatrix = None, distortionCoefficients = None, undistortedImageMultiplication = None): | |
| 76 self.name = name | |
| 77 self.resX = resX | |
| 78 self.resY = resY | |
| 79 self.frameRate = frameRate | |
| 80 self.frameRateTimeUnit = frameRateTimeUnit | |
| 81 self.undistort = False | |
| 82 | |
| 83 if trackingConfigurationFilename is not None: | |
| 84 from storage import ProcessParameters | |
| 85 params = ProcessParameters(trackingConfigurationFilename) | |
| 86 if params.undistort: | |
| 87 self.undistort = params.undistort | |
| 88 self.intrinsicCameraMatrix = params.intrinsicCameraMatrix | |
| 89 self.distortionCoefficients = params.distortionCoefficients | |
| 90 self.undistortedImageMultiplication = params.undistortedImageMultiplication | |
| 91 elif undistort is not None: | |
| 92 self.undistort = undistort | |
| 93 self.intrinsicCameraMatrix = intrinsicCameraMatrix | |
| 94 self.distortionCoefficients = distortionCoefficients | |
| 95 self.undistortedImageMultiplication = undistortedImageMultiplication | |
| 96 | |
| 97 # populate the db | |
| 98 if hasattr(self, 'intrinsicCameraMatrix') and self.intrinsicCameraMatrix is not None\ | |
| 99 and hasattr(self, 'distortionCoefficients') and self.distortionCoefficients is not None: | |
| 100 self.intrinsicCameraMatrixStr = ' '.join('{}'.format(x) for x in self.intrinsicCameraMatrix.flatten('C')) | |
| 101 self.distortionCoefficientsStr = ' '.join('{}'.format(x)for x in self.distortionCoefficients) | |
| 102 | |
| 103 @orm.reconstructor | |
| 104 def initOnLoad(self): | |
| 105 from numpy import array | |
| 106 if len(self.intrinsicCameraMatrixStr) > 0: | |
| 107 self.intrinsicCameraMatrix = array([float(x) for x in self.intrinsicCameraMatrixStr.split(" ")]).reshape(3,3) | |
| 108 if len(self.distortionCoefficientsStr) > 0: | |
| 109 self.distortionCoefficients = [float(x) for x in self.distortionCoefficientsStr.split(" ")] | |
| 110 | |
| 56 class CameraView(Base): | 111 class CameraView(Base): |
| 57 __tablename__ = 'camera_views' | 112 __tablename__ = 'camera_views' |
| 58 idx = Column(Integer, primary_key=True) | 113 idx = Column(Integer, primary_key=True) |
| 59 frameRate = Column(Float) | 114 description = Column(String) |
| 60 homographyFilename = Column(String) # path to homograph filename, relative to the site name | 115 homographyFilename = Column(String) # path to homograph filename, relative to the site name |
| 61 cameraCalibrationFilename = Column(String) # path to full camera calibration, relative to the site name | |
| 62 siteIdx = Column(Integer, ForeignKey('sites.idx')) | 116 siteIdx = Column(Integer, ForeignKey('sites.idx')) |
| 117 cameraTypeIdx = Column(Integer, ForeignKey('camera_types.idx')) | |
| 63 homographyDistanceUnit = Column(String, default = 'm') # make sure it is default in the database | 118 homographyDistanceUnit = Column(String, default = 'm') # make sure it is default in the database |
| 64 configurationFilename = Column(String) # path to configuration .cfg file, relative to site name | 119 trackingConfigurationFilename = Column(String) # path to configuration .cfg file, relative to site name |
| 65 | 120 |
| 66 site = relationship("Site", backref=backref('camera_views', order_by = idx)) | 121 site = relationship("Site", backref=backref('sites', order_by = idx)) |
| 67 | 122 cameraType = relationship('CameraType', backref=backref('camera_views', order_by = idx)) |
| 68 def __init__(self, frameRate, homographyFilename, cameraCalibrationFilename, site, configurationFilename): | 123 |
| 69 self.frameRate = frameRate | 124 def __init__(self, description, homographyFilename, site, cameraType, trackingConfigurationFilename): |
| 125 self.description = description | |
| 70 self.homographyFilename = homographyFilename | 126 self.homographyFilename = homographyFilename |
| 71 self.site = site | 127 self.site = site |
| 72 self.configurationFilename = configurationFilename | 128 self.cameraType = cameraType |
| 129 self.trackingConfigurationFilename = trackingConfigurationFilename | |
| 73 | 130 |
| 74 def getHomographyFilename(self, relativeToSiteFilename = True): | 131 def getHomographyFilename(self, relativeToSiteFilename = True): |
| 75 if relativeToSiteFilename: | 132 if relativeToSiteFilename: |
| 76 return self.site.getFilename()+path.sep+self.homographyFilename | 133 return self.site.getFilename()+path.sep+self.homographyFilename |
| 77 else: | 134 else: |
| 78 return self.homographyFilename | 135 return self.homographyFilename |
| 136 | |
| 137 def getTrackingConfigurationFilename(self, relativeToSiteFilename = True): | |
| 138 if relativeToSiteFilename: | |
| 139 return self.site.getFilename()+path.sep+self.trackingConfigurationFilename | |
| 140 else: | |
| 141 return self.trackingConfigurationFilename | |
| 142 | |
| 143 def getTrackingParameters(self): | |
| 144 return ProcessParameters(getTrackingConfigurationFilename()) | |
| 79 | 145 |
| 80 class Alignment(Base): | 146 class Alignment(Base): |
| 81 __tablename__ = 'alignments' | 147 __tablename__ = 'alignments' |
| 82 idx = Column(Integer, primary_key=True) | 148 idx = Column(Integer, primary_key=True) |
| 83 cameraViewIdx = Column(Integer, ForeignKey('camera_views.idx')) | 149 cameraViewIdx = Column(Integer, ForeignKey('camera_views.idx')) |
| 105 class VideoSequence(Base): | 171 class VideoSequence(Base): |
| 106 __tablename__ = 'video_sequences' | 172 __tablename__ = 'video_sequences' |
| 107 idx = Column(Integer, primary_key=True) | 173 idx = Column(Integer, primary_key=True) |
| 108 name = Column(String) # path relative to the the site name | 174 name = Column(String) # path relative to the the site name |
| 109 startTime = Column(DateTime) | 175 startTime = Column(DateTime) |
| 110 duration = Column(Float) # video sequence duration | 176 duration = Column(Interval) # video sequence duration |
| 111 durationUnit = Column(String, default = 's') | 177 databaseFilename = Column(String) # path relative to the the site name |
| 112 siteIdx = Column(Integer, ForeignKey('sites.idx')) | 178 siteIdx = Column(Integer, ForeignKey('sites.idx')) |
| 113 cameraViewIdx = Column(Integer, ForeignKey('camera_views.idx')) | 179 cameraViewIdx = Column(Integer, ForeignKey('camera_views.idx')) |
| 114 configurationFilename = Column(String) | |
| 115 | 180 |
| 116 site = relationship("Site", backref=backref('video_sequences', order_by = idx)) | 181 site = relationship("Site", backref=backref('video_sequences', order_by = idx)) |
| 117 cameraView = relationship("CameraView", backref=backref('video_sequences', order_by = idx)) | 182 cameraView = relationship("CameraView", backref=backref('video_sequences', order_by = idx)) |
| 118 | 183 |
| 119 def __init__(self, name, startTime, duration, site, cameraView, configurationFilename = None): | 184 def __init__(self, name, startTime, duration, site, cameraView, databaseFilename = None): |
| 120 'startTime is passed as string in utils.datetimeFormat, eg 2011-06-22 10:00:39' | 185 '''startTime is passed as string in utils.datetimeFormat, eg 2011-06-22 10:00:39 |
| 186 duration is a timedelta object''' | |
| 121 self.name = name | 187 self.name = name |
| 122 self.startTime = datetime.strptime(startTime, datetimeFormat) | 188 self.startTime = datetime.strptime(startTime, datetimeFormat) |
| 123 self.duration = duration | 189 self.duration = duration |
| 124 self.site = site | 190 self.site = site |
| 125 self.cameraView = cameraView | 191 self.cameraView = cameraView |
| 126 self.configurationFilename = configurationFilename | 192 if databaseFilename is None and len(self.name) > 0: |
| 193 self.databaseFilename = removeExtension(self.name)+'.sqlite' | |
| 127 | 194 |
| 128 def getVideoSequenceFilename(self, relativeToSiteFilename = True): | 195 def getVideoSequenceFilename(self, relativeToSiteFilename = True): |
| 129 if relativeToSiteFilename: | 196 if relativeToSiteFilename: |
| 130 return self.site.getFilename()+path.sep+self.name | 197 return self.site.getFilename()+path.sep+self.name |
| 131 else: | 198 else: |
| 132 return self.name | 199 return self.name |
| 133 | 200 |
| 134 #def getConfigurationFilename(self): | 201 def containsInstant(self, instant): |
| 135 #'returns the local configuration filename, or the one of the camera view otherwise' | 202 'instant is a datetime' |
| 203 return self.startTime <= instant and self.startTime+self.duration | |
| 204 | |
| 205 def getFrameNum(self, instant): | |
| 206 'Warning, there is no check of correct time units' | |
| 207 if self.containsInstant(instant): | |
| 208 return int(floor((instant-self.startTime).seconds*self.cameraView.cameraType.frameRate)) | |
| 209 else: | |
| 210 return None | |
| 136 | 211 |
| 137 # 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) | 212 # 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) |
| 138 | 213 |
| 139 # class SiteDescription(Base): # list of lines and polygons describing the site, eg for sidewalks, center lines | 214 # class SiteDescription(Base): # list of lines and polygons describing the site, eg for sidewalks, center lines |
| 140 | 215 |
