changeset 1219:8a626226793e

update where optimization uses either nomad-parameter file depending on optimizing 1 or 2 steps
author Nicolas Saunier <nicolas.saunier@polymtl.ca>
date Mon, 19 Jun 2023 17:09:56 -0400
parents 1f0b1fc172f8
children 2dc9899b73ae
files scripts/dltrack.py scripts/nomad/nomad-parameters-4.txt scripts/nomad/nomad-parameters.txt scripts/nomad/optimize-with-nomad.py scripts/nomad/site-parameters-optimization.py trafficintelligence/moving.py
diffstat 6 files changed, 91 insertions(+), 63 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/dltrack.py	Mon Jun 19 17:09:56 2023 -0400
@@ -0,0 +1,27 @@
+#! /usr/bin/env python3
+# from https://docs.ultralytics.com/modes/track/
+import sys, argparse
+
+from trafficintelligence.moving import cocoUserTypeNames
+from ultralytics import YOLO
+
+parser = argparse.ArgumentParser(description='The program tracks objects following the ultralytics yolo executable.')#, epilog = 'Either the configuration filename or the other parameters (at least video and database filenames) need to be provided.')
+parser.add_argument('-i', dest = 'videoFilename', help = 'name of the video file (overrides the configuration file)')
+# detect model
+# tracker model
+parser.add_argument('--display', dest = 'display', help = 'show the results (careful with long videos, risk of running out of memory)', action = 'store_true')
+args = parser.parse_args()
+
+# Load a model
+model = YOLO('/home/nicolas/Research/Data/classification-models/yolov8x.pt ') # seg yolov8x-seg.pt
+# seg could be used on cropped image... if can be loaded and kept in memory
+# model = YOLO('/home/nicolas/Research/Data/classification-models/yolo_nas_l.pt ') # AttributeError: 'YoloNAS_L' object has no attribute 'get'
+
+# Track with the model
+if args.display:
+    results = model.track(source=args.videoFilename, tracker="/home/nicolas/Research/Data/classification-models/bytetrack.yaml", classes=list(cocoUserTypeNames.keys()), show=True) # , save_txt=True 
+else:
+    results = model.track(source=args.videoFilename, tracker="/home/nicolas/Research/Data/classification-models/bytetrack.yaml", classes=list(cocoUserTypeNames.keys()), stream=True)
+    for result in results:
+        for box in result.boxes:
+            print(box.xyxy)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/nomad/nomad-parameters-4.txt	Mon Jun 19 17:09:56 2023 -0400
@@ -0,0 +1,30 @@
+DIMENSION	4						# number of variables
+
+BB_EXE		"$python3 site-parameters-optimization.py"      # 'site-parameters-optimization.py' is the blackbox program
+BB_OUTPUT_TYPE	OBJ					        # object will be minimized
+
+X0		initial-parameters-4.txt                        # starting point
+
+LOWER_BOUND	( 2 0.1 0.1 1.0 )			  	# all variables' lower bounds
+UPPER_BOUND	( 100 10 5 15 )					# all variables' upper bounds
+
+MAX_BB_EVAL	500						# the algorithm terminates when
+								# n black-box evaluations have
+								# been made
+							  
+# TMP_DIR	/tmp						# indicates a directory where
+								# temporary files are put
+								# (increases performance by ~100%
+								# if you're working on a network
+								# account and if TMP_DIR is on a
+								# local disk)
+
+DISPLAY_DEGREE 2 
+
+# DISPLAY_ALL_EVAL yes
+
+DISPLAY_STATS BBE ( SOL ) OBJ					# Display the number of evaluation (BBE),
+                                                                # the current solution ( SOL ) and the objective
+
+# STATS_FILE test.txt BBE ( SOL ) OBJ
+HISTORY_FILE	      history.txt
--- a/scripts/nomad/nomad-parameters.txt	Sat Jun 17 08:48:22 2023 -0400
+++ b/scripts/nomad/nomad-parameters.txt	Mon Jun 19 17:09:56 2023 -0400
@@ -5,7 +5,7 @@
 
 X0		initial-parameters.txt                          # starting point
 
-LOWER_BOUND	( 0 0  1  0.01 2   0.1 0.1 1.01  )			# all variables' lower bounds
+LOWER_BOUND	( 0 0  1  0.01 2 0.1 0.1 1.0)			# all variables' lower bounds
 UPPER_BOUND	( 1 10 10 0.3  100 10 5 15 )			# all variables' upper bounds
 
 MAX_BB_EVAL	500						# the algorithm terminates when
--- a/scripts/nomad/optimize-with-nomad.py	Sat Jun 17 08:48:22 2023 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,29 +0,0 @@
-import os
-import argparse
-
-parser = argparse.ArgumentParser(description='The program is used to select the type of tracking to run with '
-                                             'tracking-mota.py with NOMAD',
-                                 epilog='''NOMAD - A blackbox optimization software: 
-                                 C. Audet, S. Le Digabel, C. Tribes and V. Rochon Montplaisir. The NOMAD project. 
-                                 Software available at https://www.gerad.ca/nomad.
-                                 
-                                 S. Le Digabel. Algorithm 909: NOMAD: Nonlinear Optimization with the MADS algorithm. 
-                                 ACM Transactions on Mathematical Software, 37(4):44:1–44:15, 2011.''',
-                                 formatter_class=argparse.RawDescriptionHelpFormatter)
-
-parser.add_argument('-t', dest='intersections', nargs = '*', type = str, help='name of the intersection for which '
-                                                    'the optimization is meant to be ran',
-                    required=True)
-parser.add_argument('--optimize-grouping-only', dest='optimizeGroupingOnly',
-                    help='optimize only the grouping parameters and not the ones associated with feature tracking',
-                    action='store_true')
-
-args = parser.parse_args()
-
-with open('arguments.txt', 'w') as f:
-    f.write(str(args.intersections))
-    f.write("\n")
-    f.write(str(args.optimizeGroupingOnly))
-
-os.system('nomad nomad-parameters.txt initial-parameters.txt')
-
--- a/scripts/nomad/site-parameters-optimization.py	Sat Jun 17 08:48:22 2023 -0400
+++ b/scripts/nomad/site-parameters-optimization.py	Mon Jun 19 17:09:56 2023 -0400
@@ -7,7 +7,7 @@
 import numpy as np
 
 
-def loadParametersStartProcess(filename):
+def loadParametersStartProcess(filename, intersections):
     # load initial parameters from x.txt
     f = open(filename, 'r+')
     l = f.readline()
@@ -18,13 +18,12 @@
     para = paraValueList(x)
     
     # run process including trackingfeature, groupfeature, load groundtruth, compute mota
-    print(process(para, intersections, optimizeGroupingOnly))
+    print(process(para, intersections))
 
 def paraValueList(x):
     #create para-value list
     #list of the 8 parameters and their values
-    pn = 8
-    p = pn*[None]
+    p = 8*[None]
     p[0] = '--feature-quality'             #]0.-0.4]
     p[1] = '--min-feature-distanceklt'     #]0.-6]
     p[2] = '--window-size'                 #[1-10]integer
@@ -35,12 +34,16 @@
     p[7] = '--min-nfeatures-group'         #[2-4]
     
     para = []
-    for n in range(pn):
-        para = para + [p[n],x[n]]
+    if len(x) == 4:
+        for n in range(4):
+            para = para + [p[4+n],x[n]]
+    else:
+        for n in range(len(x)):
+            para = para + [p[n],x[n]]
     
     return para
 
-def process(para, intersections, optimizeGroupingOnly):
+def process(para, intersections):
     Mota = []
     gtDatabaseaAbsPaths = []
     configFileAbsPaths = []
@@ -58,13 +61,15 @@
         os.chdir(cwd)
     for gtDatabaseAbsPath, configFileAbsPath in zip(gtDatabaseaAbsPaths, configFileAbsPaths):
         gtDatabaseBasename = gtDatabaseAbsPath[:-10]
-        videoFilename = gtDatabaseBasename + ".MP4"
+        videoFilename = gtDatabaseBasename + ".avi" # careful, it may be necessary to check video type / extension
+        if not os.path.exists(videoFilename):
+            print('Video file {} does not exist'.format(videoFilename))
         databaseFilename = gtDatabaseBasename + ".sqlite"
         gtDatabaseDirname = os.path.dirname(gtDatabaseAbsPath)
         homographyFilename = gtDatabaseDirname + "/homography.txt"
         maskFilename = gtDatabaseDirname + "/mask.png"
         # Skip feature tracking if the user specified to optimize only grouping parameters
-        if not optimizeGroupingOnly:
+        if len(para) > 8:
             # Track features
             trackingFeature(para, configFileAbsPath, videoFilename, databaseFilename, homographyFilename, maskFilename)
         # Group features
@@ -91,7 +96,7 @@
     # trackingfeature command parameters
     tf = ['feature-based-tracking', config, '--tf', '--video-filename', video, '--database-filename', db, '--homography-filename', homo, '--mask-filename', mask]
     # run in command line and print directly
-    subprocess.check_output(tf + para[0:10])
+    subprocess.check_output(tf + para)
 
 def groupFeature(para, config, video, db, homo, mask):
     #remove previous grouping
@@ -99,24 +104,19 @@
     #groupfeature command parameters
     gf = ['feature-based-tracking', config, '--gf', '--video-filename', video, '--database-filename', db, '--homography-filename', homo, '--mask-filename', mask]
     #run in command line and print directly
-    subprocess.check_output(gf + para[8:16])  # ['--min-feature-time', 'x', '--mm-connection-distance', 'x', '--mm-segmentation-distance', 'x', '--min-nfeatures-group', 'x']
-
-def computeMota(annotations, objects, Mota):
-    matchingDistance = 5
-    firstInstant = 0
-    lastInstant = 50000
-    return moving.computeClearMOT(annotations, objects, matchingDistance, firstInstant, lastInstant)[1]
+    subprocess.check_output(gf + para)  # ['--min-feature-time', 'x', '--mm-connection-distance', 'x', '--mm-segmentation-distance', 'x', '--min-nfeatures-group', 'x']
 
 
 if __name__ == "__main__":
     # Load args that were given with select-arguments.py
-    with open('arguments.txt', 'r') as f:
-        args = f.read().split('\n')
-        intersections = args[0]
-        optimizeGroupingOnly = args[1]
-        # Convert string representation of list into list
-        intersections = eval(intersections)
+    # with open('arguments.txt', 'r') as f:
+    #     args = f.read().split('\n')
+    #     intersections = args[0]
+    #     optimizeGroupingOnly = eval(args[1])
+    #     intersections = eval(intersections)
+    
+    # Just write the intersections to optimize here
+    intersections = ['../12-laurier']
 
-    loadParametersStartProcess(sys.argv[1])
+    loadParametersStartProcess(sys.argv[1], intersections)
     sys.exit(0)
-
--- a/trafficintelligence/moving.py	Sat Jun 17 08:48:22 2023 -0400
+++ b/trafficintelligence/moving.py	Mon Jun 19 17:09:56 2023 -0400
@@ -1363,14 +1363,14 @@
                  'truck',
                  'automated']
 
-coco2UserTypes = {1: 2, 2: 4, 3: 1, 6: 5, 8: 6}
-cocoUserTypeNames = {1: person,
-                     2: bicycle,
-	             3:	car,
-                     4: motorcycle,
-                     6: bus,
-                     7: train,
-                     8: truck}
+coco2UserTypes = {0: 2, 1: 4, 2: 1, 5: 5, 7: 6}
+cocoUserTypeNames = {0: 'person',
+                     1: 'bicycle',
+	             2:	'car',
+                     3: 'motorcycle',
+                     5: 'bus',
+                     6: 'train',
+                     7: 'truck'}
 
 userType2Num = utils.inverseEnumeration(userTypeNames)