changeset 1014:026f6b3b122c

Moving pull request2
author Wendlasida
date Fri, 01 Jun 2018 17:32:52 -0400
parents d6f121ded971 (current diff) 75af46516b2b (diff)
children cf9d29de3dbf
files python/moving.py
diffstat 10 files changed, 89 insertions(+), 23 deletions(-) [+]
line wrap: on
line diff
--- a/c/Makefile	Fri Jun 01 17:29:01 2018 -0400
+++ b/c/Makefile	Fri Jun 01 17:32:52 2018 -0400
@@ -11,7 +11,7 @@
 #LDFLAGS = -Wl,-Bstatic -lm
 LDFLAGS = -lm
 LDFLAGS += -lTrajectoryManagementAndAnalysis -lsqlite3
-LDFLAGS += -lboost_program_options
+LDFLAGS += -lboost_program_options -lboost_filesystem -lboost_system
 #LDFLAGS += -lfltk
 
 CFLAGS = -Wall -W -Wextra -std=c++11
--- a/c/Parameters.cpp	Fri Jun 01 17:29:01 2018 -0400
+++ b/c/Parameters.cpp	Fri Jun 01 17:32:52 2018 -0400
@@ -1,11 +1,14 @@
 #include "Parameters.hpp"
 
 #include <boost/program_options.hpp>
+#include <boost/filesystem.hpp>
 
 #include <iostream>
 #include <fstream>
 
 namespace po = boost::program_options;
+namespace fs = boost::filesystem; // soon std
+
 using namespace std;
 
 KLTFeatureTrackingParameters::KLTFeatureTrackingParameters(const int argc, char* argv[]) {
@@ -92,9 +95,10 @@
       cout << cmdLine << endl;
       exit(0);      
     }
-      
+
     cout << "Using configuration file " << configurationFilename << endl;
-
+    parentDirname = fs::path(configurationFilename).parent_path().string();
+    
     ifstream configurationFile(configurationFilename.c_str());
     store(po::parse_config_file(configurationFile, cmdLineAndFile, true), vm);
     notify(vm);
--- a/c/feature-based-tracking.cpp	Fri Jun 01 17:29:01 2018 -0400
+++ b/c/feature-based-tracking.cpp	Fri Jun 01 17:32:52 2018 -0400
@@ -16,6 +16,7 @@
 #include "opencv2/calib3d/calib3d.hpp"
 
 #include <boost/foreach.hpp>
+#include <boost/filesystem.hpp>
 
 #include <iostream>
 #include <vector>
@@ -24,6 +25,8 @@
 #include <memory>
 #include <limits>
 
+namespace fs = boost::filesystem; // soon std
+
 using namespace std;
 using namespace cv;
 
@@ -63,7 +66,8 @@
 }
 
 void trackFeatures(const KLTFeatureTrackingParameters& params) {
-  Mat homography = ::loadMat(params.homographyFilename, " ");
+  Mat homography = ::loadMat(::getRelativeFilename(params.parentDirname, params.homographyFilename), " ");
+    
   Mat invHomography;
   if (params.display && !homography.empty())
     invHomography = homography.inv();
@@ -90,8 +94,8 @@
     cout << "Empty video filename. Exiting." << endl;
     exit(0);
   }
-    
-  VideoCapture capture(params.videoFilename);
+
+  VideoCapture capture(::getRelativeFilename(params.parentDirname, params.videoFilename));
   if(!capture.isOpened()) {
     cout << "Video filename " << params.videoFilename << " could not be opened. Exiting." << endl;
     exit(0);
@@ -113,7 +117,7 @@
   Mat map1, map2;
   Mat intrinsicCameraMatrix, newIntrinsicCameraMatrix;
   if (params.undistort) {
-    intrinsicCameraMatrix = ::loadMat(params.intrinsicCameraFilename, " ");
+    intrinsicCameraMatrix = ::loadMat(::getRelativeFilename(params.parentDirname, params.intrinsicCameraFilename), " ");
     Size undistortedVideoSize = Size(static_cast<int>(round(videoSize.width*params.undistortedImageMultiplication)), static_cast<int>(round(videoSize.height*params.undistortedImageMultiplication)));
     newIntrinsicCameraMatrix = getDefaultNewCameraMatrix(intrinsicCameraMatrix, undistortedVideoSize, true);// for some reason, it's double type //getOptimalNewCameraMatrix(intrinsicCameraMatrix, params.distortionCoefficients, videoSize, 1, undistortedVideoSize);//, 0, true);
     initUndistortRectifyMap(intrinsicCameraMatrix, params.distortionCoefficients, Mat::eye(3,3, CV_32FC1) /* 0 ?*/, newIntrinsicCameraMatrix, undistortedVideoSize, CV_32FC1, map1, map2);
@@ -122,14 +126,14 @@
       ", height=" << undistortedVideoSize.height << endl;
   }
   
-  Mat mask = imread(params.maskFilename, 0);
+  Mat mask = imread(::getRelativeFilename(params.parentDirname, params.maskFilename), 0);
   if (mask.empty()) {
     cout << "Mask filename " << params.maskFilename << " could not be opened." << endl;
     mask = Mat::ones(videoSize, CV_8UC1);
   }
 
   std::shared_ptr<TrajectoryDBAccess<Point2f> > trajectoryDB = std::shared_ptr<TrajectoryDBAccess<Point2f> >(new TrajectoryDBAccessList<Point2f>());
-  trajectoryDB->connect(params.databaseFilename.c_str());
+  trajectoryDB->connect(::getRelativeFilename(params.parentDirname, params.databaseFilename).c_str());
   trajectoryDB->createTable("positions");
   trajectoryDB->createTable("velocities");
   trajectoryDB->beginTransaction();
@@ -264,7 +268,7 @@
 
 void groupFeatures(const KLTFeatureTrackingParameters& params) {
   std::shared_ptr<TrajectoryDBAccessList<Point2f> > trajectoryDB = std::shared_ptr<TrajectoryDBAccessList<Point2f> >(new TrajectoryDBAccessList<Point2f>());
-  bool success = trajectoryDB->connect(params.databaseFilename.c_str());
+  bool success = trajectoryDB->connect(::getRelativeFilename(params.parentDirname, params.databaseFilename).c_str());
   trajectoryDB->createObjectTable("objects", "objects_features");
   unsigned int savedObjectId=0;
 
@@ -339,7 +343,7 @@
 
 void loadingTimes(const KLTFeatureTrackingParameters& params) {
   std::shared_ptr<TrajectoryDBAccessList<Point2f> > trajectoryDB = std::shared_ptr<TrajectoryDBAccessList<Point2f> >(new TrajectoryDBAccessList<Point2f>());
-  bool success = trajectoryDB->connect(params.databaseFilename.c_str());
+  bool success = trajectoryDB->connect(::getRelativeFilename(params.parentDirname, params.databaseFilename).c_str());
   
   vector<std::shared_ptr<Trajectory<Point2f> > > trajectories;
   //cout << trajectories.size() << endl;
--- a/c/utils.cpp	Fri Jun 01 17:29:01 2018 -0400
+++ b/c/utils.cpp	Fri Jun 01 17:32:52 2018 -0400
@@ -1,10 +1,13 @@
 #include "utils.hpp"
 
 #include <boost/foreach.hpp>
+#include <boost/filesystem.hpp>
 
 #include <iostream>
 #include <fstream>
 
+namespace fs = boost::filesystem; // soon std
+
 using namespace std;
 
 std::vector<std::vector<float> > loadNumbers(const string& filename, const string& separator /* = " " */) {
@@ -27,6 +30,15 @@
   return result;
 }
 
+std::string getRelativeFilename(const std::string& parentDirname, const std::string& filename) {
+  fs::path parentPath(parentDirname);
+  fs::path filePath(filename);
+  if (filePath.is_absolute())
+    return filename;
+  else
+    return (parentPath/filePath).string();
+}
+
 int toInt(const std::string& s) { int i; fromString(i, s); return i;} //atoi
 
 float toFloat(const std::string& s) { float x; fromString(x, s); return x;}// lexical_cast<float>(s)
--- a/include/Parameters.hpp	Fri Jun 01 17:29:01 2018 -0400
+++ b/include/Parameters.hpp	Fri Jun 01 17:32:52 2018 -0400
@@ -18,6 +18,7 @@
   bool groupFeatures;
   bool loadingTime;
 
+  std::string parentDirname;
   std::string videoFilename;
   std::string databaseFilename;
   std::string homographyFilename;
--- a/include/utils.hpp	Fri Jun 01 17:29:01 2018 -0400
+++ b/include/utils.hpp	Fri Jun 01 17:32:52 2018 -0400
@@ -18,6 +18,9 @@
  * Warning: returns an empty string if all the lines to the end of the file are comments. */
 std::string getlineComment(std::ifstream& f);
 
+/** Get relative filename if not absolute */
+std::string getRelativeFilename(const std::string& parentDirname, const std::string& filename);
+
 /** Converts a string to an integer. */
 int toInt(const std::string& s);
 
--- a/python/cvutils.py	Fri Jun 01 17:29:01 2018 -0400
+++ b/python/cvutils.py	Fri Jun 01 17:32:52 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:29:01 2018 -0400
+++ b/python/moving.py	Fri Jun 01 17:32:52 2018 -0400
@@ -1225,7 +1225,6 @@
             newObject = MovingObject(newNum, emptyInterval, positions, velocities, userType = obj1.getUserType())
             newObject.features = [MovingObject(newNum, emptyInterval, positions, velocities, userType = obj1.getUserType())] #In case there is features to add when we recursively call concatenate 
             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:29:01 2018 -0400
+++ b/python/storage.py	Fri Jun 01 17:32:52 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:29:01 2018 -0400
+++ b/scripts/process.py	Fri Jun 01 17:32:52 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()