2727red = (255 , 0 , 0 )
2828green = (0 , 255 , 0 )
2929
30- if hasattr (dai .CameraBoardSocket , 'CAM_A' ):
31- stringToCam = {
32- 'RGB' : dai .CameraBoardSocket .CAM_A ,
33- 'LEFT' : dai .CameraBoardSocket .CAM_B ,
34- 'RIGHT' : dai .CameraBoardSocket .CAM_C ,
35- 'CAM_A' : dai .CameraBoardSocket .CAM_A ,
36- 'CAM_B' : dai .CameraBoardSocket .CAM_B ,
37- 'CAM_C' : dai .CameraBoardSocket .CAM_C ,
38- 'CAM_D' : dai .CameraBoardSocket .CAM_D ,
39- 'CAM_E' : dai .CameraBoardSocket .CAM_E ,
40- 'CAM_F' : dai .CameraBoardSocket .CAM_F ,
41- 'CAM_G' : dai .CameraBoardSocket .CAM_G ,
42- 'CAM_H' : dai .CameraBoardSocket .CAM_H
43- }
44- camToString = {
45- dai .CameraBoardSocket .CAM_A : 'RGB' ,
46- dai .CameraBoardSocket .CAM_B : 'LEFT' ,
47- dai .CameraBoardSocket .CAM_C : 'RIGHT' ,
48- dai .CameraBoardSocket .CAM_A : 'CAM_A' ,
49- dai .CameraBoardSocket .CAM_B : 'CAM_B' ,
50- dai .CameraBoardSocket .CAM_C : 'CAM_C' ,
51- dai .CameraBoardSocket .CAM_D : 'CAM_D' ,
52- dai .CameraBoardSocket .CAM_E : 'CAM_E' ,
53- dai .CameraBoardSocket .CAM_F : 'CAM_F' ,
54- dai .CameraBoardSocket .CAM_G : 'CAM_G' ,
55- dai .CameraBoardSocket .CAM_H : 'CAM_H'
56- }
57- else :
58- stringToCam = {
59- 'RGB' : dai .CameraBoardSocket .RGB ,
60- 'LEFT' : dai .CameraBoardSocket .LEFT ,
61- 'RIGHT' : dai .CameraBoardSocket .RIGHT ,
62- 'AUTO' : dai .CameraBoardSocket .AUTO ,
63- 'CAM_A' : dai .CameraBoardSocket .RGB ,
64- 'CAM_B' : dai .CameraBoardSocket .LEFT ,
65- 'CAM_C' : dai .CameraBoardSocket .RIGHT
66- }
67-
68- camToString = {
69- # dai.CameraBoardSocket.RGB : 'RGB' ,
70- # dai.CameraBoardSocket.LEFT : 'LEFT' ,
71- # dai.CameraBoardSocket.RIGHT : 'RIGHT',
72- # dai.CameraBoardSocket.AUTO : 'AUTO',
73- dai .CameraBoardSocket .RGB : 'CAM_A' ,
74- dai .CameraBoardSocket .LEFT : 'CAM_B' ,
75- dai .CameraBoardSocket .RIGHT : 'CAM_C' ,
76- }
30+
31+ stringToCam = {
32+ 'RGB' : dai .CameraBoardSocket .CAM_A ,
33+ 'LEFT' : dai .CameraBoardSocket .CAM_B ,
34+ 'RIGHT' : dai .CameraBoardSocket .CAM_C ,
35+ 'CAM_A' : dai .CameraBoardSocket .CAM_A ,
36+ 'CAM_B' : dai .CameraBoardSocket .CAM_B ,
37+ 'CAM_C' : dai .CameraBoardSocket .CAM_C ,
38+ 'CAM_D' : dai .CameraBoardSocket .CAM_D ,
39+ 'CAM_E' : dai .CameraBoardSocket .CAM_E ,
40+ 'CAM_F' : dai .CameraBoardSocket .CAM_F ,
41+ 'CAM_G' : dai .CameraBoardSocket .CAM_G ,
42+ 'CAM_H' : dai .CameraBoardSocket .CAM_H
43+ }
7744
7845
7946camToMonoRes = {
80- 'OV7251' : dai .MonoCameraProperties .SensorResolution .THE_480_P ,
81- 'OV9*82' : dai .MonoCameraProperties .SensorResolution .THE_800_P ,
82- 'OV9282' : dai .MonoCameraProperties .SensorResolution .THE_800_P ,
83- 'AR0234' : dai .MonoCameraProperties .SensorResolution .THE_1200_P ,
84- }
47+ 'OV7251' : dai .MonoCameraProperties .SensorResolution .THE_480_P ,
48+ 'OV9*82' : dai .MonoCameraProperties .SensorResolution .THE_800_P ,
49+ 'OV9282' : dai .MonoCameraProperties .SensorResolution .THE_800_P ,
50+ 'AR0234' : dai .MonoCameraProperties .SensorResolution .THE_1200_P ,
51+ }
8552
8653camToRgbRes = {
87- 'IMX378' : dai .ColorCameraProperties .SensorResolution .THE_4_K ,
88- 'IMX214' : dai .ColorCameraProperties .SensorResolution .THE_4_K ,
89- 'OV9*82' : dai .ColorCameraProperties .SensorResolution .THE_800_P ,
90- 'OV9282' : dai .ColorCameraProperties .SensorResolution .THE_800_P ,
91- 'OV9782' : dai .ColorCameraProperties .SensorResolution .THE_800_P ,
92- 'IMX582' : dai .ColorCameraProperties .SensorResolution .THE_12_MP ,
93- 'AR0234' : dai .ColorCameraProperties .SensorResolution .THE_1200_P ,
94- 'IMX296' : dai .ColorCameraProperties .SensorResolution .THE_1440X1080 ,
95- }
54+ 'IMX378' : dai .ColorCameraProperties .SensorResolution .THE_4_K ,
55+ 'IMX214' : dai .ColorCameraProperties .SensorResolution .THE_4_K ,
56+ 'OV9*82' : dai .ColorCameraProperties .SensorResolution .THE_800_P ,
57+ 'OV9282' : dai .ColorCameraProperties .SensorResolution .THE_800_P ,
58+ 'OV9782' : dai .ColorCameraProperties .SensorResolution .THE_800_P ,
59+ 'IMX582' : dai .ColorCameraProperties .SensorResolution .THE_12_MP ,
60+ 'AR0234' : dai .ColorCameraProperties .SensorResolution .THE_1200_P ,
61+ 'IMX296' : dai .ColorCameraProperties .SensorResolution .THE_1440X1080 ,
62+ }
9663
9764def create_blank (width , height , rgb_color = (0 , 0 , 0 )):
9865 """Create new image(numpy array) filled with certain color in RGB"""
@@ -164,25 +131,32 @@ def parse_args():
164131 help = "Invert horizontal axis of the camera for the display" )
165132 # parser.add_argument("-ep", "--maxEpiploarError", default="1.0", type=float, required=False,
166133 # help="Sets the maximum epiploar allowed with rectification")
167- parser .add_argument ("-cm" , "--cameraMode " , default = "perspective" , type = str ,
168- required = False , help = "Choose between perspective and Fisheye " )
134+ parser .add_argument ("-cm" , "--cameraModel " , default = "" , choices = [ " perspective", "fisheye" ] , type = str ,
135+ required = False , help = "Overwrite the camera model specified in board config file. Choose between perspective and fisheye. " )
169136 parser .add_argument ("-rlp" , "--rgbLensPosition" , default = - 1 , type = int ,
170137 required = False , help = "Set the manual lens position of the camera for calibration" )
171- parser .add_argument ("-fps" , "--fps" , default = 10 , type = int ,
172- required = False , help = "Set capture FPS for all cameras. Default: %(default)s" )
173138 parser .add_argument ("-cd" , "--captureDelay" , default = 5 , type = int ,
174139 required = False , help = "Choose how much delay to add between pressing the key and capturing the image. Default: %(default)s" )
175140 parser .add_argument ("-d" , "--debug" , default = False , action = "store_true" , help = "Enable debug logs." )
176141 parser .add_argument ("-fac" , "--factoryCalibration" , default = False , action = "store_true" ,
177142 help = "Enable writing to Factory Calibration." )
178143 parser .add_argument ("-osf" , "--outputScaleFactor" , type = float , default = 0.5 ,
179144 help = "set the scaling factor for output visualization. Default: 0.5." )
145+ parser .add_argument ('-fps' , '--framerate' , type = float , default = 10 ,
146+ help = "FPS to set for all cameras. Default: %(default)s" )
180147 parser .add_argument ("-sync" , "--minSyncTime" , type = float , default = 0.2 ,
181- help = "set the minimum time enforced between frames to keep synchronization. Default: 0.2 ." )
148+ help = "set the minimum time enforced between frames to keep synchronization. Default: %(default)s ." )
182149 parser .add_argument ("-q" , "--minQueueDepth" , type = int , default = 4 ,
183- help = "set the minimum queue depth for syncing before retrieving synced frames. Default: 1." )
184-
185-
150+ help = "set the minimum queue depth for syncing before retrieving synced frames. Default: %(default)s." )
151+ parser .add_argument ('-scp' , '--saveCalibPath' , type = str , default = "" ,
152+ help = "Save calibration file to this path" )
153+ parser .add_argument ('-dst' , '--datasetPath' , type = str , default = "dataset" ,
154+ help = "Path to dataset used for processing images" )
155+ parser .add_argument ('-mt' , '--mouseTrigger' , default = False , action = "store_true" ,
156+ help = "Enable mouse trigger for image capture" )
157+ parser .add_argument ('-l' , '--traceLevel' , type = int , default = 2 ,
158+ help = "Set the debug trace level. Default: %(default)s." )
159+
186160 options = parser .parse_args ()
187161
188162 # Set some extra defaults, `-brd` would override them
@@ -201,7 +175,6 @@ def parse_args():
201175 options .rgbLensPosition = 135
202176
203177 return options
204-
205178class MessageSync :
206179 def __init__ (self , num_queues , min_diff_timestamp , max_num_messages = 10 , min_queue_depth = 3 ):
207180 self .num_queues = num_queues
@@ -294,6 +267,7 @@ class Main:
294267 current_polygon = 0
295268 images_captured_polygon = 0
296269 images_captured = 0
270+ camera_model = "perspective"
297271
298272 def __init__ (self ):
299273 global debug
@@ -379,6 +353,10 @@ def close(self):
379353 if self .device :
380354 self .device .close ()
381355
356+ def mouse_event_callback (self , event , x , y , flags , param ):
357+ if event == cv2 .EVENT_LBUTTONDOWN :
358+ self .mouseTrigger = True
359+
382360 def is_markers_found (self , frame ):
383361 marker_corners , _ , _ = cv2 .aruco .detectMarkers (
384362 frame , self .aruco_dictionary )
@@ -404,7 +382,7 @@ def test_camera_orientation(self, frame_l, frame_r):
404382 def create_pipeline (self ):
405383 pipeline = dai .Pipeline ()
406384
407- fps = self .args .fps
385+ fps = self .args .framerate
408386 cams = {}
409387 for cam_id in self .board_config ['cameras' ]:
410388 cam_info = self .board_config ['cameras' ][cam_id ]
@@ -460,7 +438,7 @@ def parse_frame(self, frame, stream_name):
460438
461439 filename = calibUtils .image_filename (
462440 stream_name , self .current_polygon , self .images_captured )
463- cv2 .imwrite ("dataset/{ }/{}" . format ( stream_name , filename ) , frame )
441+ cv2 .imwrite (f" { str ( self . dataset_path ) } / { stream_name } /{ filename } " , frame )
464442 print ("py: Saved image as: " + str (filename ))
465443 return True
466444
@@ -552,6 +530,7 @@ def capture_images_sync(self):
552530
553531 self .display_name = "Image Window"
554532 syncCollector = MessageSync (len (self .camera_queue .keys ()), min_diff_timestamp = self .args .minSyncTime , min_queue_depth = self .args .minQueueDepth )
533+ self .mouseTrigger = False
555534
556535 # Clear events
557536 streams = self .device .getQueueEvents (list (self .camera_queue .keys ()))
@@ -675,10 +654,11 @@ def capture_images_sync(self):
675654 if key == 27 or key == ord ("q" ):
676655 print ("py: Calibration has been interrupted!" )
677656 raise SystemExit (0 )
678- elif key == ord (" " ):
657+ elif key == ord (" " ) or self . mouseTrigger :
679658 start_timer = True
680659 prev_time = time .time ()
681660 timer = self .args .captureDelay
661+ self .mouseTrigger = False
682662
683663 if start_timer == True :
684664 curr_time = time .time ()
@@ -696,6 +676,10 @@ def capture_images_sync(self):
696676 7 , (0 , 255 , 255 ),
697677 4 , cv2 .LINE_AA )
698678
679+ cv2 .namedWindow (self .display_name )
680+ if self .args .mouseTrigger :
681+ cv2 .setMouseCallback (self .display_name , self .mouse_event_callback )
682+
699683 cv2 .imshow (self .display_name , combinedImage )
700684 tried = {}
701685 allPassed = True
@@ -941,21 +925,25 @@ def capture_images(self):
941925
942926 def calibrate (self ):
943927 print ("Starting image processing" )
944- stereo_calib = calibUtils .StereoCalibration ()
945- # self.args.cameraMode = 'perspective' # hardcoded for now
946- try :
928+ stereo_calib = calibUtils .StereoCalibration (self . args . traceLevel )
929+
930+ self . camera_model = self . board_config . get ( "camera_model" , "perspective" )
947931
932+ if self .args .cameraModel != "" : # If camera model is specified in the command line, use that
933+ self .camera_model = self .args .cameraModel
934+
935+ try :
948936 # stereo_calib = StereoCalibration()
949937 print ("Starting image processingxxccx" )
950938 print (self .args .squaresX )
951939 status , result_config = stereo_calib .calibrate (
952940 self .board_config ,
953- self .dataset_path ,
941+ str ( self .dataset_path ) ,
954942 self .args .squareSizeCm ,
955943 self .args .markerSizeCm ,
956944 self .args .squaresX ,
957945 self .args .squaresY ,
958- self .args . cameraMode ,
946+ self .camera_model ,
959947 self .args .rectifiedDisp ) # Turn off enable disp rectify
960948
961949 calibration_handler = dai .CalibrationHandler ()
@@ -1014,6 +1002,10 @@ def prepare_calibration_handler(self, result_config, calibration_handler):
10141002 calibration_handler .setDistortionCoefficients (stringToCam [camera ], cam_info ['dist_coeff' ])
10151003 calibration_handler .setCameraIntrinsics (stringToCam [camera ], cam_info ['intrinsics' ], cam_info ['size' ][0 ], cam_info ['size' ][1 ])
10161004 calibration_handler .setFov (stringToCam [camera ], cam_info ['hfov' ])
1005+ if self .camera_model == "perspective" :
1006+ calibration_handler .setCameraType (stringToCam [camera ], dai .CameraModel .Perspective )
1007+ elif self .camera_model == "fisheye" :
1008+ calibration_handler .setCameraType (stringToCam [camera ], dai .CameraModel .Fisheye )
10171009
10181010 if 'hasAutofocus' in cam_info and cam_info ['hasAutofocus' ]:
10191011 calibration_handler .setLensPosition (stringToCam [camera ], self .focus_value )
@@ -1088,7 +1080,14 @@ def flash(self, result_config):
10881080 eeepromData .version = 7
10891081 print (f'EEPROM VERSION being flashed is -> { eeepromData .version } ' )
10901082 mx_serial_id = self .device .getDeviceInfo ().getMxId ()
1091- calib_dest_path = self .dest_path / f"{ mx_serial_id } .json"
1083+
1084+ calib_dest_folder = self .dest_path
1085+ if self .args .saveCalibPath :
1086+ calib_dest_folder = Path (self .args .saveCalibPath )
1087+ calib_dest_folder .mkdir (parents = True , exist_ok = True )
1088+
1089+ calib_dest_path = calib_dest_folder / f"{ mx_serial_id } .json"
1090+
10921091 calibration_handler .eepromToJsonFile (calib_dest_path )
10931092 # try:
10941093 self .device .flashCalibration2 (calibration_handler )
@@ -1144,21 +1143,29 @@ def flash(self, result_config):
11441143
11451144
11461145 def run (self ):
1146+
1147+ if self .args .datasetPath :
1148+ self .dataset_path = Path (self .args .datasetPath )
1149+ else :
1150+ self .dataset_path = Path ("dataset" ).absolute ()
1151+
1152+ self .dataset_path .mkdir (parents = True , exist_ok = True )
1153+
11471154 if 'capture' in self .args .mode :
11481155 try :
1149- if Path ( 'dataset' ) .exists ():
1150- shutil .rmtree ('dataset/' )
1156+ if self . dataset_path .exists ():
1157+ shutil .rmtree (str ( self . dataset_path ) )
11511158 for cam_id in self .board_config ['cameras' ]:
11521159 name = self .board_config ['cameras' ][cam_id ]['name' ]
1153- Path ( "dataset/{}" . format ( name ) ).mkdir (parents = True , exist_ok = True )
1160+ ( self . dataset_path / name ).mkdir (parents = True , exist_ok = True )
11541161
11551162 except OSError :
11561163 traceback .print_exc ()
11571164 print ("An error occurred trying to create image dataset directories!" )
11581165 raise SystemExit (1 )
11591166 self .show_info_frame ()
11601167 self .capture_images_sync ()
1161- self . dataset_path = str ( Path ( "dataset" ). absolute ())
1168+
11621169 if 'process' in self .args .mode :
11631170 status , err_text , result_config = self .calibrate ()
11641171 if 'flash' in self .args .mode :
0 commit comments