changeset 1004:75601be6019f

work on process
author Nicolas Saunier <nicolas.saunier@polymtl.ca>
date Sun, 03 Jun 2018 00:21:18 -0400
parents 75af46516b2b
children 666b38437d9a
files python/cvutils.py python/metadata.py python/storage.py scripts/process.py
diffstat 4 files changed, 62 insertions(+), 22 deletions(-) [+]
line wrap: on
line diff
--- a/python/cvutils.py	Fri Jun 01 17:19:31 2018 -0400
+++ b/python/cvutils.py	Sun Jun 03 00:21:18 2018 -0400
@@ -18,7 +18,7 @@
     
 from sys import stdout
 from os import listdir
-from subprocess import check_call
+from subprocess import run
 from math import floor, log10, ceil
 
 from numpy import dot, array, append, float32, loadtxt, savetxt, append, zeros, ones, identity, abs as npabs, logical_and, unravel_index, sum as npsum, isnan, mgrid, median, floor as npfloor, ceil as npceil
@@ -282,7 +282,7 @@
         else:
             return None
 
-    def tracking(configFilename, grouping, videoFilename = None, dbFilename = None, homographyFilename = None, maskFilename = None, undistort = False, intrinsicCameraMatrix = None, distortionCoefficients = None):
+    def tracking(configFilename, grouping, videoFilename = None, dbFilename = None, homographyFilename = None, maskFilename = None, undistort = False, intrinsicCameraMatrix = None, distortionCoefficients = None, dryRun = False):
         '''Runs the tracker in a subprocess
         if grouping is True, it is feature grouping
         otherwise it is feature tracking'''
@@ -303,14 +303,16 @@
         if undistort:
             cmd += ['--undistort', 'true']
             if intrinsicCameraMatrix is not None: # we currently have to save a file
-                pass#from time import time
-                #savetxt
-                #cmd += []
+                from time import time
+                intrinsicCameraFilename = '/tmp/intrinsic-{}.txt'.format(time())
+                savetxt(intrinsicCameraFilename, intrinsicCameraMatrix)
+                cmd += ['--intrinsic-camera-filename', intrinsicCameraFilename]
             if distortionCoefficients is not None:
                 cmd += ['--distortion-coefficients', ' '.join([str(x) for x in distortionCoefficients])]
-                
-        #check_call([trackerExe, configFilename, trackingMode]) # , stderr = out, shell = True
-        print(cmd) # , stderr = out, shell = True
+        if dryRun:
+            print(cmd)
+        else:
+            run(cmd)
         
     def displayTrajectories(videoFilename, objects, boundingBoxes = {}, homography = None, firstFrameNum = 0, lastFrameNumArg = None, printFrames = True, rescale = 1., nFramesStep = 1, saveAllImages = False, nZerosFilenameArg = None, undistort = False, intrinsicCameraMatrix = None, distortionCoefficients = None, undistortedImageMultiplication = 1., annotations = [], gtMatches = {}, toMatches = {}, colorBlind = False):
         '''Displays the objects overlaid frame by frame over the video '''
--- a/python/metadata.py	Fri Jun 01 17:19:31 2018 -0400
+++ b/python/metadata.py	Sun Jun 03 00:21:18 2018 -0400
@@ -350,12 +350,17 @@
     Session = sessionmaker(bind=engine)
     return Session()
 
-def getSite(session, siteId):
+def getSite(session, siteId = None, name = None, description = None):
     'Returns the site(s) matching the index or the name'
-    if str.isdigit(siteId):
+    if siteId is not None:
         return session.query(Site).filter(Site.idx == int(siteId)).all()
+    elif name is not None:
+        return session.query(Site).filter(Site.description.like('%'+name+'%')).all()
+    elif description is not None:
+        return session.query(Site).filter(Site.description.like('%'+description+'%')).all()
     else:
-        return session.query(Site).filter(Site.description.like('%'+siteId+'%')).all()
+        print('No siteId, name or description have been provided to the function')
+        return []
 
 def getCameraView(session, viewId):
     'Returns the site(s) matching the index'
@@ -405,3 +410,6 @@
             startTime += duration
     session.add_all(videoSequences)
     session.commit()
+
+# management
+# TODO need to be able to copy everything from a site from one sqlite to another, and delete everything attached to a site
--- a/python/storage.py	Fri Jun 01 17:19:31 2018 -0400
+++ b/python/storage.py	Sun Jun 03 00:21:18 2018 -0400
@@ -966,9 +966,9 @@
               "DELETE FROM curvilinear_positions WHERE trajectory_id IS NULL OR trajectory_id = \"NO\";\n")
     out.close()
     # system call
-    from subprocess import check_call
+    from subprocess import run
     out = openCheck("err.log", "w")
-    check_call("sqlite3 "+utils.removeExtension(filename)+".sqlite < "+sqlScriptFilename, stderr = out, shell = True)
+    run("sqlite3 "+utils.removeExtension(filename)+".sqlite < "+sqlScriptFilename, stderr = out)
     out.close()
     shutil.os.remove(sqlScriptFilename)
 
--- a/scripts/process.py	Fri Jun 01 17:19:31 2018 -0400
+++ b/scripts/process.py	Sun Jun 03 00:21:18 2018 -0400
@@ -2,18 +2,20 @@
 
 import sys, argparse
 from pathlib import Path
+from multiprocessing.pool import Pool
 
 import matplotlib
 matplotlib.use('Agg')
 import matplotlib.pyplot as plt
 from numpy import percentile
 
-import storage, events, prediction
+import storage, events, prediction, cvutils
 from metadata import *
 
 parser = argparse.ArgumentParser(description='This program manages the processing of several files based on a description of the sites and video data in an SQLite database following the metadata module.')
 parser.add_argument('--db', dest = 'metadataFilename', help = 'name of the metadata file', required = True)
 parser.add_argument('--videos', dest = 'videoIds', help = 'indices of the video sequences', nargs = '*', type = int)
+parser.add_argument('--sites', dest = 'siteIds', help = 'indices of the video sequences', nargs = '*', type = int)
 parser.add_argument('--cfg', dest = 'configFilename', help = 'name of the configuration file')
 parser.add_argument('-n', dest = 'nObjects', help = 'number of objects/interactions to process', type = int)
 parser.add_argument('--prediction-method', dest = 'predictionMethod', help = 'prediction method (constant velocity (cvd: vector computation (approximate); cve: equation solving; cv: discrete time (approximate)), normal adaptation, point set prediction)', choices = ['cvd', 'cve', 'cv', 'na', 'ps', 'mp'])
@@ -46,15 +48,43 @@
             vs = session.query(VideoSequence).get(videoId)
             storage.deleteFromSqlite(str(parentDir/vs.getDatabaseFilename()), args.delete)
 
+import time
+def track(i):
+    time.sleep(1)
+    print('process {}'.format(i))
+
+            
 if args.process in ['feature', 'object']: # tracking
-    for videoId in args.videoIds:
-        vs = session.query(VideoSequence).get(videoId)
-        if args.configFilename is None:
-            configFilename = vs.cameraView.getTrackingConfigurationFilename()
-        else:
-            configFilename = args.configFilename
-        #todo cvutils.tracking(configFilename, args.process == 'object', str(parentDir/vs.getVideoSequenceFilename(), str(parentDir/vs.getDatabaseFilename(), configFilename = vs.cameraView.getHomographyFilename())
-    
+    if args.videoIds is not None:
+        videoSequences = [session.query(VideoSequence).get(videoId) for videoId in args.videoIds]
+    elif args.siteIds is not None:
+        videoSequences = []
+        for siteId in args.siteIds:
+            for site in getSite(session, siteId):
+                for cv in site.cameraViews:
+                    videoSequences += cv.videoSequences
+    else:
+        print('No video/site to process')
+        videoSequences = []
+    if args.nProcesses == 1:
+        pass
+    else:
+        pool = Pool(args.nProcesses)
+        for vs in videoSequences:
+            if not (parentDir/vs.getDatabaseFilename()).exists():
+                if args.configFilename is None:
+                    configFilename = 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, True))
+                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, True))
+            else:
+                print('SQLite already exists: {}'.format(parentDir/vs.getDatabaseFilename()))
+        pool.close()
+        pool.join()
+
 elif args.process == 'interaction':
     # safety analysis TODO make function in safety analysis script
     if args.predictionMethod == 'cvd':