2020CSV_HEADER = "TimeStamp,MxID,RealDistance,DetectedDistance,planeFitMSE,gtPlaneMSE,planeFitRMSE," \
2121 "gtPlaneRMSE,fillRate,pixelsNo,Result,Side"
2222mx_id = None
23- product = None
23+ product = ''
2424inter_conv = None
2525
2626
2727class Ui_DepthTest (object ):
2828 def setupUi (self , DepthTest ):
2929 DepthTest .setObjectName ("DepthTest" )
30- DepthTest .resize (1074 , 723 )
30+ DepthTest .resize (1095 , 762 )
3131 font = QtGui .QFont ()
3232 font .setPointSize (14 )
3333 DepthTest .setFont (font )
@@ -127,7 +127,7 @@ def setupUi(self, DepthTest):
127127 self .l_plane_fit_rmse .setFont (font )
128128 self .l_plane_fit_rmse .setObjectName ("l_plane_fit_rmse" )
129129 self .board_group = QtWidgets .QGroupBox (self .centralwidget )
130- self .board_group .setGeometry (QtCore .QRect (410 , 520 , 151 , 131 ))
130+ self .board_group .setGeometry (QtCore .QRect (410 , 520 , 141 , 131 ))
131131 self .board_group .setObjectName ("board_group" )
132132 self .r_left = QtWidgets .QRadioButton (self .board_group )
133133 self .r_left .setGeometry (QtCore .QRect (10 , 30 , 117 , 26 ))
@@ -141,7 +141,7 @@ def setupUi(self, DepthTest):
141141 self .r_center .setChecked (True )
142142 self .r_center .setObjectName ("r_center" )
143143 self .options_group = QtWidgets .QGroupBox (self .centralwidget )
144- self .options_group .setGeometry (QtCore .QRect (800 , 520 , 251 , 161 ))
144+ self .options_group .setGeometry (QtCore .QRect (800 , 520 , 251 , 171 ))
145145 self .options_group .setObjectName ("options_group" )
146146 self .c_lrcheck = QtWidgets .QCheckBox (self .options_group )
147147 self .c_lrcheck .setGeometry (QtCore .QRect (10 , 30 , 97 , 26 ))
@@ -167,8 +167,22 @@ def setupUi(self, DepthTest):
167167 self .c_matplot .setGeometry (QtCore .QRect (110 , 230 , 111 , 31 ))
168168 self .c_matplot .setObjectName ("c_matplot" )
169169 self .b_save = QtWidgets .QPushButton (self .centralwidget )
170- self .b_save .setGeometry (QtCore .QRect (600 , 580 , 151 , 51 ))
170+ self .b_save .setGeometry (QtCore .QRect (560 , 580 , 81 , 41 ))
171171 self .b_save .setObjectName ("b_save" )
172+ self .combo_res = QtWidgets .QComboBox (self .centralwidget )
173+ self .combo_res .setGeometry (QtCore .QRect (410 , 660 , 201 , 36 ))
174+ self .combo_res .setObjectName ("combo_res" )
175+ self .combo_res .addItem ("" )
176+ self .combo_res .addItem ("" )
177+ self .combo_res .addItem ("" )
178+ self .combo_res .addItem ("" )
179+ self .combo_res .addItem ("" )
180+ self .c_ir = QtWidgets .QCheckBox (self .centralwidget )
181+ self .c_ir .setGeometry (QtCore .QRect (640 , 650 , 131 , 31 ))
182+ self .c_ir .setObjectName ("c_ir" )
183+ self .b_export = QtWidgets .QPushButton (self .centralwidget )
184+ self .b_export .setGeometry (QtCore .QRect (650 , 580 , 141 , 41 ))
185+ self .b_export .setObjectName ("b_export" )
172186 DepthTest .setCentralWidget (self .centralwidget )
173187 self .statusbar = QtWidgets .QStatusBar (DepthTest )
174188 self .statusbar .setObjectName ("statusbar" )
@@ -211,24 +225,38 @@ def retranslateUi(self, DepthTest):
211225 self .c_lrcheck .setText (_translate ("DepthTest" , "lrcheck" ))
212226 self .c_extended .setText (_translate ("DepthTest" , "extended" ))
213227 self .c_subpixel .setText (_translate ("DepthTest" , "subpixel" ))
214- self .c_distrotion .setText (_translate ("DepthTest" , "distortionCorrection " ))
228+ self .c_distrotion .setText (_translate ("DepthTest" , "distortion correction " ))
215229 self .l_pixels_no .setText (_translate ("DepthTest" , "-" ))
216230 self .c_matplot .setText (_translate ("DepthTest" , "Matplot" ))
217231 self .b_save .setText (_translate ("DepthTest" , "Save" ))
232+ self .combo_res .setItemText (0 , _translate ("DepthTest" , "Auto" ))
233+ self .combo_res .setItemText (1 , _translate ("DepthTest" , "800p" ))
234+ self .combo_res .setItemText (2 , _translate ("DepthTest" , "720p" ))
235+ self .combo_res .setItemText (3 , _translate ("DepthTest" , "480p" ))
236+ self .combo_res .setItemText (4 , _translate ("DepthTest" , "400p" ))
237+ self .c_ir .setText (_translate ("DepthTest" , "enable IR" ))
238+ self .b_export .setText (_translate ("DepthTest" , "Export Depth" ))
218239
219240
220241class Camera :
221- def __init__ (self , lrcheck , subpixel , extended , distortion ):
242+ def __init__ (self , lrcheck , subpixel , extended , distortion , resolution ):
222243 # get mono resolution
223244 cam_res = {
224245 'OV7251' : dai .MonoCameraProperties .SensorResolution .THE_480_P ,
225246 'OV9*82' : dai .MonoCameraProperties .SensorResolution .THE_800_P ,
226- 'OV9282' : dai .MonoCameraProperties .SensorResolution .THE_800_P
247+ 'OV9282' : dai .MonoCameraProperties .SensorResolution .THE_800_P ,
248+ '800p' : dai .MonoCameraProperties .SensorResolution .THE_800_P ,
249+ '720p' : dai .MonoCameraProperties .SensorResolution .THE_720_P ,
250+ '480p' : dai .MonoCameraProperties .SensorResolution .THE_480_P ,
251+ '400p' : dai .MonoCameraProperties .SensorResolution .THE_400_P
227252 }
228253 self .device = dai .Device ()
229254 # print(self.device.getDeviceInfo().getXLinkDeviceDesc())
230255 sensors = self .device .getCameraSensorNames ()
231- mono_resolution = cam_res [sensors [dai .CameraBoardSocket .LEFT ]]
256+ if resolution == 'Auto' :
257+ mono_resolution = cam_res [sensors [dai .CameraBoardSocket .LEFT ]]
258+ else :
259+ mono_resolution = cam_res [resolution ]
232260 if mono_resolution is dai .MonoCameraProperties .SensorResolution .THE_400_P :
233261 self .resolution = (640 , 400 )
234262 elif mono_resolution is dai .MonoCameraProperties .SensorResolution .THE_480_P :
@@ -260,7 +288,6 @@ def __init__(self, lrcheck, subpixel, extended, distortion):
260288 stereo .initialConfig .setMedianFilter (dai .MedianFilter .KERNEL_3x3 )
261289 stereo .setDefaultProfilePreset (dai .node .StereoDepth .PresetMode .HIGH_DENSITY )
262290 stereo .setRectifyEdgeFillColor (0 ) # black, to better see the cutout
263- stereo .initialConfig .setMedianFilter (dai .StereoDepthProperties .MedianFilter .MEDIAN_OFF )
264291 stereo .setLeftRightCheck (lrcheck )
265292 stereo .setSubpixel (subpixel )
266293 stereo .setExtendedDisparity (extended )
@@ -290,6 +317,18 @@ def __init__(self, lrcheck, subpixel, extended, distortion):
290317 self .depthQueue = self .device .getOutputQueue (name = "depth" , maxSize = 4 , blocking = False )
291318 # self.spatialCalcQueue = self.device.getOutputQueue(name="spatialData", maxSize=4, blocking=False)
292319
320+ def set_ir (self , state ):
321+ try :
322+ if state :
323+ self .device .setIrFloodLightBrightness (250 )
324+ self .device .setIrLaserDotProjectorBrightness (100 )
325+ else :
326+ self .device .setIrFloodLightBrightness (0 )
327+ self .device .setIrLaserDotProjectorBrightness (0 )
328+ return True
329+ except :
330+ return False
331+
293332 def get_frame (self ):
294333 in_depth = self .depthQueue .tryGet ()
295334 if in_depth is None :
@@ -356,6 +395,7 @@ def __init__(self, roi):
356395 self .depth_frame = None
357396
358397 def get_depth_frame (self ):
398+ self .update_frame ()
359399 return self .depth_frame
360400
361401 def get_roi (self ):
@@ -407,17 +447,24 @@ def mouseReleaseEvent(self, event: 'QGraphicsSceneMouseEvent') -> None:
407447 self .p2 [1 ] = clamp (self .p2 [1 ], 0 , self .height )
408448 self .roi .update (self .p1 , self .p2 )
409449
410- def enable_camera (self , lrcheck , subpixel , extended , distortion ):
411- self .camera = Camera (lrcheck , subpixel , extended , distortion )
450+ def enable_camera (self , lrcheck , subpixel , extended , distortion , resolution ):
451+ self .camera = Camera (lrcheck , subpixel , extended , distortion , resolution )
412452 self .cameraEnabled = True
413453
454+ def set_ir (self , state ):
455+ return self .camera .set_ir (state )
456+
414457 def disable_camera (self ):
415458 self .camera .device .close ()
416459 self .cameraEnabled = False
417- if self .pixmap is not None :
418- self .pixmap .fill ()
460+ if self .pixmap is None :
461+ return
462+ self .pixmap .fill ()
419463 self .setPixmap (self .pixmap )
420464
465+ def is_enabled (self ):
466+ return self .cameraEnabled
467+
421468
422469class Scene (QtWidgets .QGraphicsScene ):
423470 def __init__ (self , dialog ):
@@ -504,6 +551,8 @@ class Application(QtWidgets.QMainWindow):
504551 def __init__ (self ):
505552 super ().__init__ ()
506553 # DepthTest = QtWidgets.QMainWindow()
554+ self .ir = False
555+ self .roi_depth_np = None
507556 self .pixels_no = 0
508557 self .fill_rate = None
509558 self .gt_plane_rmse = None
@@ -518,10 +567,11 @@ def __init__(self):
518567 # self.ui.preview_video.onm
519568 self .ui .b_connect .clicked .connect (self .button_event )
520569 self .ui .b_save .clicked .connect (self .save_csv )
570+ self .ui .b_export .clicked .connect (self .save_depth_array )
521571 self .ui .b_save .setDisabled (True )
522572 self .timer = QtCore .QTimer ()
523573 self .timer .timeout .connect (self .timer_event )
524- self .timer .start (1000 // 30 )
574+ # self.timer.start(1000 // 30)
525575 try : #TODO Find a way to scan for USB ports
526576 self .serial_reader = serial .Serial ("/dev/ttyUSB0" , 115200 )
527577 except :
@@ -535,6 +585,8 @@ def __init__(self):
535585 self .set_result ('' )
536586 self .z_distance = 0
537587 self .plot_fit_plane = None
588+ self .ui .c_ir .setDisabled (True )
589+ self .ui .b_export .setDisabled (True )
538590
539591 def set_plot (self ):
540592 # Plot Setup
@@ -565,8 +617,12 @@ def button_event(self):
565617 self .ui .l_test .setText ('Depth Test' )
566618 self .ui .options_group .setDisabled (False )
567619 self .set_result ('' )
620+ self .timer .stop ()
621+ self .ui .combo_res .setEnabled (True )
622+ self .ui .c_ir .setDisabled (True )
623+ self .ui .b_export .setDisabled (True )
568624 else :
569- self .scene .get_frame ().enable_camera (self .ui .c_lrcheck .isChecked (), self .ui .c_subpixel .isChecked (), self .ui .c_extended .isChecked (), self .ui .c_distrotion .isChecked ())
625+ self .scene .get_frame ().enable_camera (self .ui .c_lrcheck .isChecked (), self .ui .c_subpixel .isChecked (), self .ui .c_extended .isChecked (), self .ui .c_distrotion .isChecked (), self . ui . combo_res . currentText () )
570626 self .count = 0
571627 self .pass_count = 0
572628 self .fail_count = 0
@@ -578,10 +634,32 @@ def button_event(self):
578634 self .ui .b_save .setEnabled (True )
579635 self .ui .l_test .setText (str (product ))
580636 self .ui .options_group .setDisabled (True )
637+ self .timer .start (1000 // 30 )
638+ self .ui .combo_res .setDisabled (True )
639+ if self .scene .get_frame ().set_ir (False ):
640+ self .ui .c_ir .setEnabled (True )
641+ self .ui .b_export .setEnabled (True )
642+
643+ def save_depth_array (self ):
644+ self .ui .b_export .setDisabled (True )
645+ path = os .path .realpath (__file__ ).rsplit ('/' , 1 )[0 ] + f'/depth_result/{ str (product )} .npz'
646+ side = ''
647+ if self .ui .r_left .isChecked ():
648+ side = 'left'
649+ elif self .ui .r_right .isChecked ():
650+ side = 'right'
651+ elif self .ui .r_center .isChecked ():
652+ side = 'center'
653+ save_data = {}
654+ if os .path .exists (path ):
655+ save_data = np .load (path )
656+ save_data = dict (save_data )
657+ save_data [f'{ mx_id } _{ side } _{ self .true_distance } ' ] = self .roi_depth_np
658+ np .savez (path , ** save_data )
659+ self .ui .b_export .setEnabled (True )
581660
582661 def save_csv (self ):
583- path = os .path .realpath (__file__ ).rsplit ('/' , 1 )[0 ] + '/depth_result/' + str (product ) + '.csv'
584- # print(path)
662+ path = os .path .realpath (__file__ ).rsplit ('/' , 1 )[0 ] + f'/depth_result/{ str (product )} .csv'
585663 if os .path .exists (path ):
586664 file = open (path , 'a' )
587665 else :
@@ -611,6 +689,7 @@ def calculate_errors(self):
611689 coord = pixel_coord_np (* sbox , * ebox )
612690 # Removing Zeros from coordinates
613691 cam_coords = np .dot (inter_conv , coord ) * depth_roi .flatten () / 1000.0
692+ self .roi_depth_np = cam_coords
614693 # Removing outliers from Z coordinates. top and bottoom 0.5 percentile of valid depth
615694 try :
616695 valid_cam_coords = np .delete (cam_coords , np .where (cam_coords [2 , :] == 0.0 ), axis = 1 )
@@ -637,19 +716,8 @@ def calculate_errors(self):
637716 subsampled_pixels = np .array (subsampled_pixels ).transpose ()
638717 sub_points3D = np .dot (inter_conv , subsampled_pixels ) * subsampled_pixels_depth .flatten () / 1000.0 # [x, y, z]
639718 sub_points3D = sub_points3D .transpose ()
640- # sc._offsets3d = (sub_points3D[:, 0], sub_points3D[:, 1], sub_points3D[:, 2]) #3D Plot
641719 c , normal = fit_plane_LTSQ (sub_points3D )
642- # maxx = np.max(sub_points3D[:, 0])
643- # maxy = np.max(sub_points3D[:, 1])
644- # minx = np.min(sub_points3D[:, 0])
645- # miny = np.min(sub_points3D[:, 1])
646- #
647720 d = - np .array ([0.0 , 0.0 , c ]).dot (normal )
648- # # fitPlane = (normal, d)
649- # xx, yy = np.meshgrid([minx, maxx], [miny, maxy])
650- # self.z_distance = (-normal[0] * xx - normal[1] * yy - d) * 1. / normal[2]
651- # print("Distance of subpixel from plane")
652- # print(sub_points3D[0].dot(normal) + d)
653721 plane_offset_error = 0
654722 gt_offset_error = 0
655723 planeR_ms_offset_rror = 0
@@ -704,7 +772,10 @@ def calculate_errors(self):
704772 return True
705773
706774 def timer_event (self ):
707- self .scene .get_frame ().update_frame ()
775+ if self .ui .c_ir .isEnabled ():
776+ if self .ir != self .ui .c_ir .isChecked ():
777+ self .ir = self .ui .c_ir .isChecked ()
778+ self .scene .get_frame ().set_ir (self .ir )
708779 if not self .calculate_errors ():
709780 return
710781
0 commit comments