changeset 1021:16932cefabc1

work on paths in line with new configurations from tracker
author Nicolas Saunier <nicolas.saunier@polymtl.ca>
date Tue, 05 Jun 2018 17:02:28 -0400
parents 9fb82fe0156f
children b7689372c0ec
files python/cvutils.py python/storage.py python/utils.py scripts/info-video.py scripts/init-tracking.py scripts/process.py
diffstat 6 files changed, 69 insertions(+), 44 deletions(-) [+]
line wrap: on
line diff
--- a/python/cvutils.py	Tue Jun 05 14:33:31 2018 -0400
+++ b/python/cvutils.py	Tue Jun 05 17:02:28 2018 -0400
@@ -290,7 +290,7 @@
             trackingMode = '--gf'
         else:
             trackingMode = '--tf'
-        cmd = [trackerExe, configFilename, trackingMode]
+        cmd = [trackerExe, configFilename, trackingMode, '--quiet']
         
         if videoFilename is not None:
             cmd += ['--video-filename', videoFilename]
--- a/python/storage.py	Tue Jun 05 14:33:31 2018 -0400
+++ b/python/storage.py	Tue Jun 05 17:02:28 2018 -0400
@@ -1277,10 +1277,12 @@
 
         config = ConfigParser()
         config.read_file(addSectionHeader(openCheck(filename)))
+
+        parentPath = Path(filename).parent
         self.sectionHeader = config.sections()[0]
 
-        self.pedBikeCarSVMFilename = config.get(self.sectionHeader, 'pbv-svm-filename')
-        self.bikeCarSVMFilename = config.get(self.sectionHeader, 'bv-svm-filename')
+        self.pedBikeCarSVMFilename = utils.getRelativeFilename(parentPath, config.get(self.sectionHeader, 'pbv-svm-filename'))
+        self.bikeCarSVMFilename = utils.getRelativeFilename(parentPath, config.get(self.sectionHeader, 'bv-svm-filename'))
         self.percentIncreaseCrop = config.getfloat(self.sectionHeader, 'percent-increase-crop')
         self.minNPixels = config.getint(self.sectionHeader, 'min-npixels-crop')
         x  = config.getint(self.sectionHeader, 'hog-rescale-size')
@@ -1345,16 +1347,17 @@
         config = ConfigParser(strict=False)
         config.read_file(addSectionHeader(openCheck(filename)))
 
+        parentPath = Path(filename).parent
         self.sectionHeader = config.sections()[0]
         # Tracking/display parameters
-        self.videoFilename = config.get(self.sectionHeader, 'video-filename')
-        self.databaseFilename = config.get(self.sectionHeader, 'database-filename')
-        self.homographyFilename = config.get(self.sectionHeader, 'homography-filename')
+        self.videoFilename = utils.getRelativeFilename(parentPath, config.get(self.sectionHeader, 'video-filename'))
+        self.databaseFilename = utils.getRelativeFilename(parentPath, config.get(self.sectionHeader, 'database-filename'))
+        self.homographyFilename = utils.getRelativeFilename(parentPath, config.get(self.sectionHeader, 'homography-filename'))
         if Path(self.homographyFilename).exists():
             self.homography = loadtxt(self.homographyFilename)
         else:
             self.homography = None
-        self.intrinsicCameraFilename = config.get(self.sectionHeader, 'intrinsic-camera-filename')
+        self.intrinsicCameraFilename = utils.getRelativeFilename(parentPath, config.get(self.sectionHeader, 'intrinsic-camera-filename'))
         if Path(self.intrinsicCameraFilename).exists():
             self.intrinsicCameraMatrix = loadtxt(self.intrinsicCameraFilename)
         else:
@@ -1368,7 +1371,7 @@
 
         self.minFeatureTime = config.getfloat(self.sectionHeader, 'min-feature-time')
         
-        self.classifierFilename = config.get(self.sectionHeader, 'classifier-filename')
+        self.classifierFilename = utils.getRelativeFilename(parentPath, config.get(self.sectionHeader, 'classifier-filename'))
         
         # Safety parameters
         self.maxPredictedSpeed = config.getfloat(self.sectionHeader, 'max-predicted-speed')/3.6/self.videoFrameRate
@@ -1398,6 +1401,7 @@
     '''Loads information from configuration file
     then checks what was passed on the command line
     for override (eg video filename and database filename'''
+    parentPath = Path(args.configFilename).parent
     if args.configFilename is not None: # consider there is a configuration file
         params = ProcessParameters(args.configFilename)
         videoFilename = params.videoFilename
@@ -1421,12 +1425,13 @@
         firstFrameNum = 0
 
     # override video and database filenames if present on command line
+    # if not absolute, make all filenames relative to the location of the configuration filename
     if args.videoFilename is not None:
-        videoFilename = args.videoFilename
+        videoFilename = utils.getRelativeFilename(parentPath, args.videoFilename)
     else:
         videoFilename = params.videoFilename
     if args.databaseFilename is not None:
-        databaseFilename = args.databaseFilename
+        databaseFilename = utils.getRelativeFilename(parentPath, args.databaseFilename)
     else:
         databaseFilename = params.databaseFilename
 
--- a/python/utils.py	Tue Jun 05 14:33:31 2018 -0400
+++ b/python/utils.py	Tue Jun 05 17:02:28 2018 -0400
@@ -5,6 +5,7 @@
 import matplotlib.pyplot as plt
 from datetime import time, datetime
 from argparse import ArgumentTypeError
+from pathlib import Path
 from math import sqrt, ceil, floor
 from scipy.stats import kruskal, shapiro, lognorm
 from scipy.spatial import distance
@@ -971,31 +972,42 @@
     'cleans filenames obtained when contatenating figure characteristics'
     return s.replace(' ','-').replace('.','').replace('/','-').replace(',','')
 
+def getRelativeFilename(parentPath, filename):
+    'Returns filename if absolute, otherwise parentPath/filename as string'
+    filePath = Path(filename)
+    if filePath.is_absolute():
+        return filename
+    else:
+        return str(parentPath/filePath)
+
 def listfiles(dirname, extension, remove = False):
     '''Returns the list of files with the extension in the directory dirname
     If remove is True, the filenames are stripped from the extension'''
-    from os import listdir
-    tmp = [f for f in listdir(dirname) if f.endswith(extension)]
-    tmp.sort()
-    if remove:
-        return [removeExtension(f, extension) for f in tmp]
+    d = Path(dirname)
+    if d.is_dir():
+        tmp = [str(f) for f in d.glob('*.extension')]
+        if remove:
+            return [removeExtension(f, extension) for f in tmp]
+        else:
+            return tmp
     else:
-        return tmp
+        print(dirname+' is not a directory')
+        return []
 
 def mkdir(dirname):
     'Creates a directory if it does not exist'
-    import os
-    if not os.path.exists(dirname):
-        os.mkdir(dirname)
+    p = Path(dirname)
+    if not p.exists():
+        p.mkdir()
     else:
         print(dirname+' already exists')
 
 def removeFile(filename):
     '''Deletes the file while avoiding raising an error 
     if the file does not exist'''
-    import os
-    if (os.path.exists(filename)):
-        os.remove(filename)
+    f = Path(filename)
+    if (f.exists()):
+        f.unlink()
     else:
         print(filename+' does not exist')
 
--- a/scripts/info-video.py	Tue Jun 05 14:33:31 2018 -0400
+++ b/scripts/info-video.py	Tue Jun 05 17:02:28 2018 -0400
@@ -10,5 +10,5 @@
 args = parser.parse_args()
 
 videoProperties = cvutils.infoVideo(args.videoFilename)
-for k,v in videoProperties.iteritems():
+for k,v in videoProperties.items():
     print('Video {}: {}'.format(k, v))
--- a/scripts/init-tracking.py	Tue Jun 05 14:33:31 2018 -0400
+++ b/scripts/init-tracking.py	Tue Jun 05 17:02:28 2018 -0400
@@ -11,6 +11,7 @@
 parser = argparse.ArgumentParser(description='The program initilizes the files for tracking: copy tracking.cfg, sets up with the video filename, generates a frame image (frame.png) and prints the next commands')
 
 parser.add_argument('-i', dest = 'videoFilename', help = 'filename of the video sequence', required = True)
+parser.add_argument('-n', dest = 'nFrames', help = 'number of frames to extract', type = int)
 
 args = parser.parse_args()
 
@@ -45,12 +46,19 @@
         print('Configuration file classifier.cfg successfully copied to the current directory')
         
 # extract image from video
-image = getImagesFromVideo(args.videoFilename, saveImage = True, outputPrefix = 'frame')
+if args.nFrames is not None:
+    image = getImagesFromVideo(args.videoFilename, 0, args.nFrames, saveImage = True, outputPrefix = 'frame')
+else:
+    image = getImagesFromVideo(args.videoFilename, saveImage = True, outputPrefix = 'frame')
 print('first video frame successfully copied to the current directory')
 
 # next commands
-print('--------------------------------------\nHere are a sample of the next command to compute the homography,\ntrack features, group them in objects and display object trajectories\n--------------------------------------')
-print('compute_homography -i [frame.png] -w [world_image] -n [npoints] -u [unit_per_pixel]')
+print('''--------------------------------------
+Here are a sample of the next command to compute the homography,
+track features, group them in objects and display object trajectories
+--------------------------------------''')
+print('compute-homography -i [frame.png] -w [world_image] -n [npoints] -u [unit_per_pixel]')
+print('(beware of camera distortion)')
 print('feature-based-tracking tracking.cfg --tf')
 print('feature-based-tracking tracking.cfg --gf')
 print('display-trajectories --cfg tracking.cfg -t object')
--- a/scripts/process.py	Tue Jun 05 14:33:31 2018 -0400
+++ b/scripts/process.py	Tue Jun 05 17:02:28 2018 -0400
@@ -40,7 +40,7 @@
 # Data preparation
 #################################
 session = connectDatabase(args.metadataFilename)
-parentDir = Path(args.metadataFilename).parent # files are relative to metadata location
+parentPath = Path(args.metadataFilename).parent # files are relative to metadata location
 videoSequences = []
 if args.videoIds is not None:
     videoSequences = [session.query(VideoSequence).get(videoId) for videoId in args.videoIds]
@@ -61,7 +61,7 @@
     elif args.delete in ['object', 'interaction']:
         #parser.add_argument('-t', dest = 'dataType', help = 'type of the data to remove', required = True, choices = ['object','interaction', 'bb', 'pois', 'prototype'])
         for vs in videoSequences:
-            storage.deleteFromSqlite(str(parentDir/vs.getDatabaseFilename()), args.delete)
+            storage.deleteFromSqlite(str(parentPath/vs.getDatabaseFilename()), args.delete)
 
 #################################
 # Process
@@ -69,31 +69,31 @@
 if args.process in ['feature', 'object']: # tracking
     if args.nProcesses == 1:
         for vs in videoSequences:
-            if not (parentDir/vs.getDatabaseFilename()).exists() or args.process == 'object':
+            if not (parentPath/vs.getDatabaseFilename()).exists() or args.process == 'object':
                 if args.configFilename is None:
-                    configFilename = str(parentDir/vs.cameraView.getTrackingConfigurationFilename())
+                    configFilename = str(parentPath/vs.cameraView.getTrackingConfigurationFilename())
                 else:
                     configFilename = args.configFilename
                 if vs.cameraView.cameraType is None:
-                    cvutils.tracking(configFilename, args.process == 'object', str(parentDir.absolute()/vs.getVideoSequenceFilename()), str(parentDir.absolute()/vs.getDatabaseFilename()), str(parentDir.absolute()/vs.cameraView.getHomographyFilename()), str(parentDir.absolute()/vs.cameraView.getMaskFilename()), False, None, None, args.dryRun)
+                    cvutils.tracking(configFilename, args.process == 'object', str(parentPath.absolute()/vs.getVideoSequenceFilename()), str(parentPath.absolute()/vs.getDatabaseFilename()), str(parentPath.absolute()/vs.cameraView.getHomographyFilename()), str(parentPath.absolute()/vs.cameraView.getMaskFilename()), False, None, None, args.dryRun)
                 else:
-                    cvutils.tracking(configFilename, args.process == 'object', str(parentDir.absolute()/vs.getVideoSequenceFilename()), str(parentDir.absolute()/vs.getDatabaseFilename()), str(parentDir.absolute()/vs.cameraView.getHomographyFilename()), str(parentDir.absolute()/vs.cameraView.getMaskFilename()), True, vs.cameraView.cameraType.intrinsicCameraMatrix, vs.cameraView.cameraType.distortionCoefficients, args.dryRun)
+                    cvutils.tracking(configFilename, args.process == 'object', str(parentPath.absolute()/vs.getVideoSequenceFilename()), str(parentPath.absolute()/vs.getDatabaseFilename()), str(parentPath.absolute()/vs.cameraView.getHomographyFilename()), str(parentPath.absolute()/vs.cameraView.getMaskFilename()), True, vs.cameraView.cameraType.intrinsicCameraMatrix, vs.cameraView.cameraType.distortionCoefficients, args.dryRun)
             else:
-                print('SQLite already exists: {}'.format(parentDir/vs.getDatabaseFilename()))
+                print('SQLite already exists: {}'.format(parentPath/vs.getDatabaseFilename()))
     else:
         pool = Pool(args.nProcesses)
         for vs in videoSequences:
-            if not (parentDir/vs.getDatabaseFilename()).exists() or args.process == 'object':
+            if not (parentPath/vs.getDatabaseFilename()).exists() or args.process == 'object':
                 if args.configFilename is None:
-                    configFilename = str(parentDir/vs.cameraView.getTrackingConfigurationFilename())
+                    configFilename = str(parentPath/vs.cameraView.getTrackingConfigurationFilename())
                 else:
                     configFilename = args.configFilename
                 if vs.cameraView.cameraType is None:
-                    pool.apply_async(cvutils.tracking, args = (configFilename, args.process == 'object', str(parentDir.absolute()/vs.getVideoSequenceFilename()), str(parentDir.absolute()/vs.getDatabaseFilename()), str(parentDir.absolute()/vs.cameraView.getHomographyFilename()), str(parentDir.absolute()/vs.cameraView.getMaskFilename()), False, None, None, args.dryRun))
+                    pool.apply_async(cvutils.tracking, args = (configFilename, args.process == 'object', str(parentPath.absolute()/vs.getVideoSequenceFilename()), str(parentPath.absolute()/vs.getDatabaseFilename()), str(parentPath.absolute()/vs.cameraView.getHomographyFilename()), str(parentPath.absolute()/vs.cameraView.getMaskFilename()), False, None, None, args.dryRun))
                 else:
-                    pool.apply_async(cvutils.tracking, args = (configFilename, args.process == 'object', str(parentDir.absolute()/vs.getVideoSequenceFilename()), str(parentDir.absolute()/vs.getDatabaseFilename()), str(parentDir.absolute()/vs.cameraView.getHomographyFilename()), str(parentDir.absolute()/vs.cameraView.getMaskFilename()), True, vs.cameraView.cameraType.intrinsicCameraMatrix, vs.cameraView.cameraType.distortionCoefficients, args.dryRun))
+                    pool.apply_async(cvutils.tracking, args = (configFilename, args.process == 'object', str(parentPath.absolute()/vs.getVideoSequenceFilename()), str(parentPath.absolute()/vs.getDatabaseFilename()), str(parentPath.absolute()/vs.cameraView.getHomographyFilename()), str(parentPath.absolute()/vs.cameraView.getMaskFilename()), True, vs.cameraView.cameraType.intrinsicCameraMatrix, vs.cameraView.cameraType.distortionCoefficients, args.dryRun))
             else:
-                print('SQLite already exists: {}'.format(parentDir/vs.getDatabaseFilename()))
+                print('SQLite already exists: {}'.format(parentPath/vs.getDatabaseFilename()))
         pool.close()
         pool.join()
 
@@ -105,14 +105,14 @@
         predictionParameters = prediction.CVExactPredictionParameters()
     for vs in videoSequences:
         print('Processing '+vs.getDatabaseFilename())
-        objects = storage.loadTrajectoriesFromSqlite(str(parentDir/vs.getDatabaseFilename()), 'object')#, args.nObjects, withFeatures = (params.useFeaturesForPrediction or predictionMethod == 'ps' or predictionMethod == 'mp'))
+        objects = storage.loadTrajectoriesFromSqlite(str(parentPath/vs.getDatabaseFilename()), 'object')#, args.nObjects, withFeatures = (params.useFeaturesForPrediction or predictionMethod == 'ps' or predictionMethod == 'mp'))
         interactions = events.createInteractions(objects)
         #if args.nProcesses == 1:
-        #print(str(parentDir/vs.cameraView.getTrackingConfigurationFilename()))
-        params = storage.ProcessParameters(str(parentDir/vs.cameraView.getTrackingConfigurationFilename()))
+        #print(str(parentPath/vs.cameraView.getTrackingConfigurationFilename()))
+        params = storage.ProcessParameters(str(parentPath/vs.cameraView.getTrackingConfigurationFilename()))
         #print(len(interactions), args.computePET, predictionParameters, params.collisionDistance, params.predictionTimeHorizon, params.crossingZones)
         processed = events.computeIndicators(interactions, True, args.computePET, predictionParameters, params.collisionDistance, params.predictionTimeHorizon, params.crossingZones, False, None)
-        storage.saveIndicatorsToSqlite(str(parentDir/vs.getDatabaseFilename()), processed)
+        storage.saveIndicatorsToSqlite(str(parentPath/vs.getDatabaseFilename()), processed)
     # else:
     #     pool = Pool(processes = args.nProcesses)
     #     nInteractionPerProcess = int(np.ceil(len(interactions)/float(args.nProcesses)))
@@ -134,7 +134,7 @@
             medianSpeeds[vs.cameraView.siteIdx] = []
             speeds85[vs.cameraView.siteIdx] = []
         print('Extracting speed from '+vs.getDatabaseFilename())
-        objects = storage.loadTrajectoriesFromSqlite(str(parentDir/vs.getDatabaseFilename()), 'object')
+        objects = storage.loadTrajectoriesFromSqlite(str(parentPath/vs.getDatabaseFilename()), 'object')
         for o in objects:
             if o.length() > minLength:
                 speeds = 30*3.6*percentile(o.getSpeeds(), [50, 85])
@@ -160,7 +160,7 @@
             indicators[vs.cameraView.siteIdx] = {}
             for i in indicatorIds:
                 indicators[vs.cameraView.siteIdx][i] = []
-        interactions[vs.cameraView.siteIdx] += storage.loadInteractionsFromSqlite(str(parentDir/vs.getDatabaseFilename()))
+        interactions[vs.cameraView.siteIdx] += storage.loadInteractionsFromSqlite(str(parentPath/vs.getDatabaseFilename()))
         print(vs.getDatabaseFilename(), len(interactions[vs.cameraView.siteIdx]))
         for inter in interactions[vs.cameraView.siteIdx]:
             for i in indicatorIds: