changeset 819:fc8b3ce629d1

important modifications to metadata
author Nicolas Saunier <nicolas.saunier@polymtl.ca>
date Wed, 22 Jun 2016 14:51:00 -0400
parents 181bcb6dad3a
children e73e7b644428
files python/metadata.py
diffstat 1 files changed, 75 insertions(+), 15 deletions(-) [+]
line wrap: on
line diff
--- a/python/metadata.py	Tue Jun 21 17:08:07 2016 -0400
+++ b/python/metadata.py	Wed Jun 22 14:51:00 2016 -0400
@@ -3,11 +3,11 @@
 from datetime import datetime
 from os import path
 
-from sqlalchemy import create_engine, Column, Integer, Float, DateTime, String, ForeignKey
+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
+from utils import datetimeFormat, removeExtension
 
 Base = declarative_base()
 
@@ -20,14 +20,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 +55,72 @@
         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)
-    frameRate = Column(Float)
     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))
+    camera = relationship('CameraType', backref=backref('camera_views', order_by = idx))
 
-    def __init__(self, frameRate, homographyFilename, cameraCalibrationFilename, site, configurationFilename):
-        self.frameRate = frameRate
+    def __init__(self, homographyFilename, site, cameraType, trackingConfigurationFilename):
         self.homographyFilename = homographyFilename
         self.site = site
-        self.configurationFilename = configurationFilename
+        self.cameraType = cameraType
+        self.trackingConfigurationFilename = trackingConfigurationFilename
 
     def getHomographyFilename(self, relativeToSiteFilename = True):
         if relativeToSiteFilename:
@@ -77,6 +128,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)
@@ -109,21 +169,22 @@
     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'))
-    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):
+    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
-        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 +192,7 @@
         else:
             return self.name
 
-        #def getConfigurationFilename(self):
-        #'returns the local configuration filename, or the one of the camera view otherwise'
+
 
 # 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)