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