1+ import os
2+ import sys
3+ import numpy as np
4+ import traceback
5+ import shutil
6+
7+
8+ eval_script_filename = "eval_3d_bbox_performance.py"
9+ eval_module_name = "eval_3d_bbox_performance"
10+ try :
11+ if not os .path .exists (eval_script_filename ):
12+ raise FileNotFoundError (f"Evaluation script '{ eval_script_filename } ' not found in the current directory." )
13+
14+ # Attempt the standard import
15+ imported_module = __import__ (eval_module_name )
16+ print (f"Module '{ eval_module_name } ' imported successfully." )
17+
18+ except :
19+ print ("##################" )
20+ print (f"{ eval_script_filename } import error" )
21+ print ("##################" )
22+ exit (1 )
23+
24+ #### Generate Dummy Data in KITTI Format #####
25+
26+ def create_dummy_kitti_data (base_dir , num_samples = 3 , classes = ['Car' , 'Pedestrian' ], boxes_per_sample = 5 , is_pred = False , noise_level = 0.1 , seed = 42 ):
27+ """Generates dummy data files in KITTI format."""
28+ if os .path .exists (base_dir ):
29+ shutil .rmtree (base_dir ) # Clean previous runs
30+ os .makedirs (base_dir )
31+ np .random .seed (seed ) # reproducibility
32+
33+ for i in range (num_samples ):
34+ filename = os .path .join (base_dir , f"{ i :06d} .txt" )
35+ with open (filename , 'w' ) as f :
36+ num_boxes = np .random .randint (1 , boxes_per_sample + 1 )
37+ for _ in range (num_boxes ):
38+ cls = np .random .choice (classes )
39+
40+ # Generate somewhat box parameters
41+ h = np .random .uniform (1.4 , 1.8 ) if cls == 'Car' else np .random .uniform (1.5 , 1.9 ) # height
42+ w = np .random .uniform (1.5 , 2.0 ) if cls == 'Car' else np .random .uniform (0.5 , 1.0 ) # width
43+ l = np .random .uniform (3.5 , 5.0 ) if cls == 'Car' else np .random .uniform (0.5 , 1.0 ) # length
44+
45+ loc_x = np .random .uniform (- 15 , 15 ) # center x (lateral)
46+ loc_z = np .random .uniform (5 , 50 ) # center z (depth)
47+ loc_y_bottom = np .random .uniform (1.6 , 1.7 ) # Approximate height of bottom relative to camera origin
48+ rot_y = np .random .uniform (- np .pi / 2 , np .pi / 2 ) # Yaw
49+
50+ # Placeholder values
51+ truncated = 0.0
52+ occluded = 0 # 0=visible
53+ alpha = - 10
54+ bbox_2d = [0.0 , 0.0 , 50.0 , 50.0 ]
55+ score = np .random .uniform (0.5 , 1.0 )
56+
57+ # Add noise for predictions
58+ if is_pred :
59+ h *= np .random .normal (1 , noise_level * 0.1 )
60+ w *= np .random .normal (1 , noise_level * 0.1 )
61+ l *= np .random .normal (1 , noise_level * 0.1 )
62+ loc_x += np .random .normal (0 , noise_level * 1.0 )
63+ loc_y_bottom += np .random .normal (0 , noise_level * 0.1 )
64+ loc_z += np .random .normal (0 , noise_level * 3.0 )
65+ rot_y += np .random .normal (0 , noise_level * np .pi / 8 )
66+ h , w , l = max (0.1 , h ), max (0.1 , w ), max (0.1 , l ) # Ensure positive dimensions
67+
68+ # Format the line string to KITTI standard
69+ line_parts = [
70+ cls , f"{ truncated :.2f} " , f"{ occluded :d} " , f"{ alpha :.2f} " ,
71+ f"{ bbox_2d [0 ]:.2f} " , f"{ bbox_2d [1 ]:.2f} " , f"{ bbox_2d [2 ]:.2f} " , f"{ bbox_2d [3 ]:.2f} " ,
72+ f"{ h :.2f} " , f"{ w :.2f} " , f"{ l :.2f} " ,
73+ f"{ loc_x :.2f} " , f"{ loc_y_bottom :.2f} " , f"{ loc_z :.2f} " ,
74+ f"{ rot_y :.2f} "
75+ ]
76+
77+ if is_pred :
78+ line_parts .append (f"{ score :.4f} " )
79+
80+ f .write (" " .join (line_parts ) + "\n " )
81+
82+ # --- Setup Directories ---
83+ base_output_dir = "./kitti_eval_demo"
84+ gt_dir = os .path .join (base_output_dir , "dummy_gt_kitti" )
85+ pred1_dir = os .path .join (base_output_dir , "dummy_pred1_kitti" )
86+ pred2_dir = os .path .join (base_output_dir , "dummy_pred2_kitti" )
87+ eval_output_dir = os .path .join (base_output_dir , "eval_output" )
88+
89+ # --- Generate KITTI-formatted Dummy Data ---
90+ print ("\n [LOG] Generating dummy data (KITTI format) for demonstration..." )
91+ try :
92+ create_dummy_kitti_data (gt_dir , num_samples = 5 , classes = ['Car' , 'Pedestrian' ], is_pred = False , seed = 42 )
93+ create_dummy_kitti_data (pred1_dir , num_samples = 5 , classes = ['Car' , 'Pedestrian' ], is_pred = True , noise_level = 0.1 , seed = 101 )
94+ create_dummy_kitti_data (pred2_dir , num_samples = 5 , classes = ['Car' , 'Pedestrian' ], is_pred = True , noise_level = 0.3 , seed = 202 )
95+ missing_pred_file = os .path .join (pred2_dir , "000004.txt" )
96+ if os .path .exists (missing_pred_file ):
97+ os .remove (missing_pred_file )
98+ print (f"Removed { missing_pred_file } to simulate missing prediction." )
99+ print ("Dummy data generated." )
100+ except Exception as e :
101+ print (f"Error generating dummy data: { e } " )
102+ traceback .print_exc ()
103+ exit (1 )
104+
105+ # --- Run the Evaluation Script ---
106+ print (f"\n [LOG] #### Run Evaluation " )
107+ cmd_args = [
108+ gt_dir ,
109+ pred1_dir ,
110+ pred2_dir ,
111+ eval_output_dir ,
112+ '--detector_names' , 'DetectorA_Imported' , 'DetectorB_Imported' ,
113+ '--iou_threshold' , '0.7' ,
114+ '--classes' , 'Car' , 'Pedestrian'
115+ ]
116+
117+
118+ original_argv = sys .argv
119+ sys .argv = [eval_script_filename ] + cmd_args
120+ exit_code = 0
121+
122+ try :
123+ print (f"[LOG] call { eval_module_name } .main()..." )
124+ imported_module .main ()
125+
126+ except AttributeError :
127+ exit_code = 1
128+ except Exception as e :
129+ traceback .print_exc ()
130+ exit_code = 1
131+ finally :
132+ # Restore original sys.argv
133+ sys .argv = original_argv
134+
135+ ##### List generated output files #####
136+ print ("\n --- Generated Output Files ---" )
137+ if os .path .exists (eval_output_dir ):
138+ try :
139+ output_files = [os .path .join (eval_output_dir , item ) for item in os .listdir (eval_output_dir )]
140+ if output_files :
141+ for item_path in sorted (output_files ): # Sort for consistent listing
142+ print (item_path )
143+ else :
144+ print (f"Output directory '{ eval_output_dir } ' is empty." )
145+ except Exception as e :
146+ print (f"Error listing output directory { eval_output_dir } : { e } " )
147+ else :
148+ print (f"Output directory '{ eval_output_dir } ' not created or accessible." )
149+
150+ # Display contents of the metrics file if execution was successful
151+ metrics_file = os .path .join (eval_output_dir , 'evaluation_metrics.txt' )
152+ if exit_code == 0 and os .path .exists (metrics_file ):
153+ print (f"\n --- Content of { metrics_file } ---" )
154+ try :
155+ with open (metrics_file , 'r' ) as f :
156+ print (f .read ())
157+ except Exception as e :
158+ print (f"Error reading metrics file { metrics_file } : { e } " )
159+ elif exit_code != 0 :
160+ # Use syntax compatible with Python < 3.8
161+ print (f"\n --- Metrics file not displayed due to execution error (exit_code={ exit_code } ) ---" )
162+ elif not os .path .exists (metrics_file ):
163+ print (f"\n --- Metrics file not found: { metrics_file } ---" )
164+
165+ print (f"\n Demo finished. Check the '{ base_output_dir } ' directory for generated data and results." )
0 commit comments