changeset 1003:75af46516b2b

work in progress
author Nicolas Saunier <nicolas.saunier@polymtl.ca>
date Fri, 01 Jun 2018 17:19:31 -0400
parents 6c5ce3ec497e
children 75601be6019f 026f6b3b122c
files python/cvutils.py python/moving.py python/storage.py scripts/process.py
diffstat 4 files changed, 54 insertions(+), 12 deletions(-) [+]
line wrap: on
line diff
--- a/python/cvutils.py	Fri Jun 01 17:19:24 2018 -0400
+++ b/python/cvutils.py	Fri Jun 01 17:19:31 2018 -0400
@@ -18,7 +18,7 @@
     
 from sys import stdout
 from os import listdir
-from copy import deepcopy
+from subprocess import check_call
 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
@@ -27,10 +27,9 @@
 from matplotlib.pyplot import imread, imsave
 
 videoFilenameExtensions = ['mov', 'avi', 'mp4', 'MOV', 'AVI', 'MP4']
-
+trackerExe = 'feature-based-tracking'
 #importaggdraw # agg on top of PIL (antialiased drawing)
 
-
 cvRed = {'default': (0,0,255),
          'colorblind': (0,114,178)}
 cvGreen = {'default': (0,255,0),
@@ -283,6 +282,36 @@
         else:
             return None
 
+    def tracking(configFilename, grouping, videoFilename = None, dbFilename = None, homographyFilename = None, maskFilename = None, undistort = False, intrinsicCameraMatrix = None, distortionCoefficients = None):
+        '''Runs the tracker in a subprocess
+        if grouping is True, it is feature grouping
+        otherwise it is feature tracking'''
+        if grouping:
+            trackingMode = '--gf'
+        else:
+            trackingMode = '--tf'
+        cmd = [trackerExe, configFilename, trackingMode]
+        
+        if videoFilename is not None:
+            cmd += ['--video-filename', videoFilename]
+        if dbFilename is not None:
+            cmd += ['--database-filename', dbFilename]
+        if homographyFilename is not None:
+            cmd += ['--homography-filename', homographyFilename]
+        if maskFilename is not None:
+            cmd += ['--mask-filename', maskFilename]
+        if undistort:
+            cmd += ['--undistort', 'true']
+            if intrinsicCameraMatrix is not None: # we currently have to save a file
+                pass#from time import time
+                #savetxt
+                #cmd += []
+            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
+        
     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 '''
         if colorBlind:
--- a/python/moving.py	Fri Jun 01 17:19:24 2018 -0400
+++ b/python/moving.py	Fri Jun 01 17:19:31 2018 -0400
@@ -1184,7 +1184,6 @@
 
             newObject = MovingObject(newNum, emptyInterval, positions, velocities, userType = obj1.getUserType())
             return MovingObject.concatenate(MovingObject.concatenate(obj1, newObject),obj2)
-                     
         else:
             newTimeInterval = TimeInterval.union(obj1.getTimeInterval(), obj2.getTimeInterval())
             # positions
--- a/python/storage.py	Fri Jun 01 17:19:24 2018 -0400
+++ b/python/storage.py	Fri Jun 01 17:19:31 2018 -0400
@@ -5,7 +5,7 @@
 import utils, moving, events, indicators, shutil
 from base import VideoFilenameAddable
 
-from os import path
+from pathlib import Path
 from copy import copy
 import sqlite3, logging
 from numpy import log, min as npmin, max as npmax, round as npround, array, sum as npsum, loadtxt, floor as npfloor, ceil as npceil, linalg
@@ -43,7 +43,7 @@
 
 def deleteFromSqlite(filename, dataType):
     'Deletes (drops) some tables in the filename depending on type of data'
-    if path.isfile(filename):
+    if Path(filename).is_file():
         with sqlite3.connect(filename) as connection:
             if dataType == 'object':
                 dropTables(connection, ['objects', 'objects_features'])
@@ -1307,7 +1307,7 @@
         self.stdVehicleSpeed = config.getfloat(self.sectionHeader, 'std-veh-speed')
 
     def __init__(self, filename = None):
-        if filename is not None and path.exists(filename):
+        if filename is not None and Path(filename).exists():
             self.loadConfigFile(filename)
         else:
             print('Configuration filename {} could not be loaded.'.format(filename))
@@ -1350,12 +1350,12 @@
         self.videoFilename = config.get(self.sectionHeader, 'video-filename')
         self.databaseFilename = config.get(self.sectionHeader, 'database-filename')
         self.homographyFilename = config.get(self.sectionHeader, 'homography-filename')
-        if path.exists(self.homographyFilename):
+        if Path(self.homographyFilename).exists():
             self.homography = loadtxt(self.homographyFilename)
         else:
             self.homography = None
         self.intrinsicCameraFilename = config.get(self.sectionHeader, 'intrinsic-camera-filename')
-        if path.exists(self.intrinsicCameraFilename):
+        if Path(self.intrinsicCameraFilename).exists():
             self.intrinsicCameraMatrix = loadtxt(self.intrinsicCameraFilename)
         else:
             self.intrinsicCameraMatrix = None
@@ -1389,7 +1389,7 @@
         self.minLcssSimilarity = config.getfloat(self.sectionHeader, 'min-lcss-similarity')
 
     def __init__(self, filename = None):
-        if filename is not None and path.exists(filename):
+        if filename is not None and Path(filename).exists():
             self.loadConfigFile(filename)
         else:
             print('Configuration filename {} could not be loaded.'.format(filename))
--- a/scripts/process.py	Fri Jun 01 17:19:24 2018 -0400
+++ b/scripts/process.py	Fri Jun 01 17:19:31 2018 -0400
@@ -1,7 +1,7 @@
 #! /usr/bin/env python3
 
 import sys, argparse
-from pathlib2 import Path
+from pathlib import Path
 
 import matplotlib
 matplotlib.use('Agg')
@@ -14,11 +14,14 @@
 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('--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'])
 parser.add_argument('--pet', dest = 'computePET', help = 'computes PET', action = 'store_true')
+# override other tracking config, erase sqlite?
 parser.add_argument('--delete', dest = 'delete', help = 'data to delete', choices = ['feature', 'object', 'classification', 'interaction'])
 parser.add_argument('--process', dest = 'process', help = 'data to process', choices = ['feature', 'object', 'classification', 'interaction'])
+parser.add_argument('--display', dest = 'display', help = 'data to display (replay over video)', choices = ['feature', 'object', 'classification', 'interaction'])
 parser.add_argument('--analyze', dest = 'analyze', help = 'data to analyze (results)', choices = ['feature', 'object', 'classification', 'interaction'])
 
 # need way of selecting sites as similar as possible to sql alchemy syntax
@@ -26,6 +29,8 @@
 # manage cfg files, overwrite them (or a subset of parameters)
 # delete sqlite files
 
+# info of metadata
+
 parser.add_argument('--nthreads', dest = 'nProcesses', help = 'number of processes to run in parallel', type = int, default = 1)
 
 args = parser.parse_args()
@@ -41,7 +46,16 @@
             vs = session.query(VideoSequence).get(videoId)
             storage.deleteFromSqlite(str(parentDir/vs.getDatabaseFilename()), args.delete)
 
-if args.process == 'interaction':
+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())
+    
+elif args.process == 'interaction':
     # safety analysis TODO make function in safety analysis script
     if args.predictionMethod == 'cvd':
         predictionParameters = prediction.CVDirectPredictionParameters()