Mercurial Hosting > traffic-intelligence
view python/metadata.py @ 819:fc8b3ce629d1
important modifications to metadata
author | Nicolas Saunier <nicolas.saunier@polymtl.ca> |
---|---|
date | Wed, 22 Jun 2016 14:51:00 -0400 |
parents | 180b6b0231c0 |
children | 26daf35180ad |
line wrap: on
line source
# from moving import Point from datetime import datetime from os import path from sqlalchemy import orm, create_engine, Column, Integer, Float, DateTime, String, ForeignKey, Boolean from sqlalchemy.orm import relationship, backref, sessionmaker from sqlalchemy.ext.declarative import declarative_base from utils import datetimeFormat, removeExtension Base = declarative_base() class Site(Base): __tablename__ = 'sites' idx = Column(Integer, primary_key=True) name = Column(String) # same as path, relative to the database position description = Column(String) # longer names, eg intersection of road1 and road2 xcoordinate = Column(Float) # ideally moving.Point, but needs to be 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., 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 class EnvironementalFactors(Base): '''Represents any environmental factors that may affect the results, in particular * changing weather conditions * changing road configuration, geometry, signalization, etc. ex: sunny, rainy, before counter-measure, after counter-measure''' __tablename__ = 'environmental_factors' idx = Column(Integer, primary_key=True) startTime = Column(DateTime) endTime = Column(DateTime) description = Column(String) # eg sunny, before, after siteIdx = Column(Integer, ForeignKey('sites.idx')) site = relationship("Site", backref=backref('environmental_factors', order_by = idx)) def __init__(self, startTime, endTime, description, site): 'startTime is passed as string in utils.datetimeFormat, eg 2011-06-22 10:00:39' self.startTime = datetime.strptime(startTime, datetimeFormat) self.endTime = datetime.strptime(endTime, datetimeFormat) 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) undistort = Column(Boolean) intrinsicCameraMatrixStr = Column(String) distortionCoefficientsStr = Column(String) undistortedImageMultiplication = Column(Float) def __init__(self, name, resX, resY, frameRate, trackingConfigurationFilename = None, undistort = None, intrinsicCameraMatrix = None, distortionCoefficients = None, undistortedImageMultiplication = None): self.name = name self.resX = resX self.resY = resY self.frameRate = frameRate 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 self.intrinsicCameraMatrix is not None 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) homographyFilename = Column(String) # path to homograph filename, 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 trackingConfigurationFilename = Column(String) # path to configuration .cfg file, relative to site name site = relationship("Site", backref=backref('sites', order_by = idx)) camera = relationship('CameraType', backref=backref('camera_views', order_by = idx)) def __init__(self, homographyFilename, site, cameraType, trackingConfigurationFilename): self.homographyFilename = homographyFilename self.site = site self.cameraType = cameraType self.trackingConfigurationFilename = trackingConfigurationFilename def getHomographyFilename(self, relativeToSiteFilename = True): if relativeToSiteFilename: return self.site.getFilename()+path.sep+self.homographyFilename 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) cameraViewIdx = Column(Integer, ForeignKey('camera_views.idx')) cameraView = relationship("CameraView", backref=backref('alignments', order_by = idx)) def __init__(self, cameraView): self.cameraView = cameraView class Point(Base): __tablename__ = 'points' alignmentIdx = Column(Integer, ForeignKey('alignments.idx'), primary_key=True) index = Column(Integer, primary_key=True) # order of points in this alignment x = Column(Float) y = Column(Float) alignment = relationship("Alignment", backref=backref('points', order_by = index)) def __init__(self, alignmentIdx, index, x, y): self.alignmentIdx = alignmentIdx self.index = index self.x = x self.y = y class VideoSequence(Base): __tablename__ = 'video_sequences' 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') databaseFilename = Column(String) # path relative to the the site name siteIdx = Column(Integer, ForeignKey('sites.idx')) cameraViewIdx = Column(Integer, ForeignKey('camera_views.idx')) 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, databaseFilename = None): 'startTime is passed as string in utils.datetimeFormat, eg 2011-06-22 10:00:39' self.name = name self.startTime = datetime.strptime(startTime, datetimeFormat) self.duration = duration self.site = site self.cameraView = cameraView if databaseFilename is None and len(self.name) > 0: self.databaseFilename = removeExtension(self.name)+'.sqlite' def getVideoSequenceFilename(self, relativeToSiteFilename = True): if relativeToSiteFilename: return self.site.getFilename()+path.sep+self.name else: return self.name # 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) # class SiteDescription(Base): # list of lines and polygons describing the site, eg for sidewalks, center lines # class Analysis(Base): # parameters necessary for processing the data: free form # eg bounding box depends on camera view, tracking configuration depends on camera view # results: sqlite def createDatabase(filename): 'creates a session to query the filename' engine = create_engine('sqlite:///'+filename) Base.metadata.create_all(engine) Session = sessionmaker(bind=engine) return Session() def connectDatabase(filename): 'creates a session to query the filename' engine = create_engine('sqlite:///'+filename) Session = sessionmaker(bind=engine) return Session() def initializeSites(session, directoryName): '''Initializes default site objects and Camera Views eg somedirectory/montreal/ contains intersection1, intersection2, etc. The site names would be somedirectory/montreal/intersection1, somedirectory/montreal/intersection2, etc.''' from os import listdir, path sites = [] cameraViews = [] names = listdir(directoryName) for name in names: if path.isdir(directoryName+'/'+name): sites.append(Site(directoryName+'/'+name, None)) cameraViews.append(CameraView(-1, None, None, sites[-1], None)) session.add_all(sites) session.add_all(cameraViews) session.commit() # TODO crawler for video files?