20
20
CSV_HEADER = "TimeStamp,MxID,RealDistance,DetectedDistance,planeFitMSE,gtPlaneMSE,planeFitRMSE," \
21
21
"gtPlaneRMSE,fillRate,pixelsNo,Result,Side"
22
22
mx_id = None
23
- product = None
23
+ product = ''
24
24
inter_conv = None
25
25
26
26
27
27
class Ui_DepthTest (object ):
28
28
def setupUi (self , DepthTest ):
29
29
DepthTest .setObjectName ("DepthTest" )
30
- DepthTest .resize (1074 , 723 )
30
+ DepthTest .resize (1095 , 762 )
31
31
font = QtGui .QFont ()
32
32
font .setPointSize (14 )
33
33
DepthTest .setFont (font )
@@ -127,7 +127,7 @@ def setupUi(self, DepthTest):
127
127
self .l_plane_fit_rmse .setFont (font )
128
128
self .l_plane_fit_rmse .setObjectName ("l_plane_fit_rmse" )
129
129
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 ))
131
131
self .board_group .setObjectName ("board_group" )
132
132
self .r_left = QtWidgets .QRadioButton (self .board_group )
133
133
self .r_left .setGeometry (QtCore .QRect (10 , 30 , 117 , 26 ))
@@ -141,7 +141,7 @@ def setupUi(self, DepthTest):
141
141
self .r_center .setChecked (True )
142
142
self .r_center .setObjectName ("r_center" )
143
143
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 ))
145
145
self .options_group .setObjectName ("options_group" )
146
146
self .c_lrcheck = QtWidgets .QCheckBox (self .options_group )
147
147
self .c_lrcheck .setGeometry (QtCore .QRect (10 , 30 , 97 , 26 ))
@@ -167,8 +167,22 @@ def setupUi(self, DepthTest):
167
167
self .c_matplot .setGeometry (QtCore .QRect (110 , 230 , 111 , 31 ))
168
168
self .c_matplot .setObjectName ("c_matplot" )
169
169
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 ))
171
171
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" )
172
186
DepthTest .setCentralWidget (self .centralwidget )
173
187
self .statusbar = QtWidgets .QStatusBar (DepthTest )
174
188
self .statusbar .setObjectName ("statusbar" )
@@ -211,24 +225,38 @@ def retranslateUi(self, DepthTest):
211
225
self .c_lrcheck .setText (_translate ("DepthTest" , "lrcheck" ))
212
226
self .c_extended .setText (_translate ("DepthTest" , "extended" ))
213
227
self .c_subpixel .setText (_translate ("DepthTest" , "subpixel" ))
214
- self .c_distrotion .setText (_translate ("DepthTest" , "distortionCorrection " ))
228
+ self .c_distrotion .setText (_translate ("DepthTest" , "distortion correction " ))
215
229
self .l_pixels_no .setText (_translate ("DepthTest" , "-" ))
216
230
self .c_matplot .setText (_translate ("DepthTest" , "Matplot" ))
217
231
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" ))
218
239
219
240
220
241
class Camera :
221
- def __init__ (self , lrcheck , subpixel , extended , distortion ):
242
+ def __init__ (self , lrcheck , subpixel , extended , distortion , resolution ):
222
243
# get mono resolution
223
244
cam_res = {
224
245
'OV7251' : dai .MonoCameraProperties .SensorResolution .THE_480_P ,
225
246
'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
227
252
}
228
253
self .device = dai .Device ()
229
254
# print(self.device.getDeviceInfo().getXLinkDeviceDesc())
230
255
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 ]
232
260
if mono_resolution is dai .MonoCameraProperties .SensorResolution .THE_400_P :
233
261
self .resolution = (640 , 400 )
234
262
elif mono_resolution is dai .MonoCameraProperties .SensorResolution .THE_480_P :
@@ -260,7 +288,6 @@ def __init__(self, lrcheck, subpixel, extended, distortion):
260
288
stereo .initialConfig .setMedianFilter (dai .MedianFilter .KERNEL_3x3 )
261
289
stereo .setDefaultProfilePreset (dai .node .StereoDepth .PresetMode .HIGH_DENSITY )
262
290
stereo .setRectifyEdgeFillColor (0 ) # black, to better see the cutout
263
- stereo .initialConfig .setMedianFilter (dai .StereoDepthProperties .MedianFilter .MEDIAN_OFF )
264
291
stereo .setLeftRightCheck (lrcheck )
265
292
stereo .setSubpixel (subpixel )
266
293
stereo .setExtendedDisparity (extended )
@@ -290,6 +317,18 @@ def __init__(self, lrcheck, subpixel, extended, distortion):
290
317
self .depthQueue = self .device .getOutputQueue (name = "depth" , maxSize = 4 , blocking = False )
291
318
# self.spatialCalcQueue = self.device.getOutputQueue(name="spatialData", maxSize=4, blocking=False)
292
319
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
+
293
332
def get_frame (self ):
294
333
in_depth = self .depthQueue .tryGet ()
295
334
if in_depth is None :
@@ -356,6 +395,7 @@ def __init__(self, roi):
356
395
self .depth_frame = None
357
396
358
397
def get_depth_frame (self ):
398
+ self .update_frame ()
359
399
return self .depth_frame
360
400
361
401
def get_roi (self ):
@@ -407,17 +447,24 @@ def mouseReleaseEvent(self, event: 'QGraphicsSceneMouseEvent') -> None:
407
447
self .p2 [1 ] = clamp (self .p2 [1 ], 0 , self .height )
408
448
self .roi .update (self .p1 , self .p2 )
409
449
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 )
412
452
self .cameraEnabled = True
413
453
454
+ def set_ir (self , state ):
455
+ return self .camera .set_ir (state )
456
+
414
457
def disable_camera (self ):
415
458
self .camera .device .close ()
416
459
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 ()
419
463
self .setPixmap (self .pixmap )
420
464
465
+ def is_enabled (self ):
466
+ return self .cameraEnabled
467
+
421
468
422
469
class Scene (QtWidgets .QGraphicsScene ):
423
470
def __init__ (self , dialog ):
@@ -504,6 +551,8 @@ class Application(QtWidgets.QMainWindow):
504
551
def __init__ (self ):
505
552
super ().__init__ ()
506
553
# DepthTest = QtWidgets.QMainWindow()
554
+ self .ir = False
555
+ self .roi_depth_np = None
507
556
self .pixels_no = 0
508
557
self .fill_rate = None
509
558
self .gt_plane_rmse = None
@@ -518,10 +567,11 @@ def __init__(self):
518
567
# self.ui.preview_video.onm
519
568
self .ui .b_connect .clicked .connect (self .button_event )
520
569
self .ui .b_save .clicked .connect (self .save_csv )
570
+ self .ui .b_export .clicked .connect (self .save_depth_array )
521
571
self .ui .b_save .setDisabled (True )
522
572
self .timer = QtCore .QTimer ()
523
573
self .timer .timeout .connect (self .timer_event )
524
- self .timer .start (1000 // 30 )
574
+ # self.timer.start(1000 // 30)
525
575
try : #TODO Find a way to scan for USB ports
526
576
self .serial_reader = serial .Serial ("/dev/ttyUSB0" , 115200 )
527
577
except :
@@ -535,6 +585,8 @@ def __init__(self):
535
585
self .set_result ('' )
536
586
self .z_distance = 0
537
587
self .plot_fit_plane = None
588
+ self .ui .c_ir .setDisabled (True )
589
+ self .ui .b_export .setDisabled (True )
538
590
539
591
def set_plot (self ):
540
592
# Plot Setup
@@ -565,8 +617,12 @@ def button_event(self):
565
617
self .ui .l_test .setText ('Depth Test' )
566
618
self .ui .options_group .setDisabled (False )
567
619
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 )
568
624
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 () )
570
626
self .count = 0
571
627
self .pass_count = 0
572
628
self .fail_count = 0
@@ -578,10 +634,32 @@ def button_event(self):
578
634
self .ui .b_save .setEnabled (True )
579
635
self .ui .l_test .setText (str (product ))
580
636
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 )
581
660
582
661
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'
585
663
if os .path .exists (path ):
586
664
file = open (path , 'a' )
587
665
else :
@@ -611,6 +689,7 @@ def calculate_errors(self):
611
689
coord = pixel_coord_np (* sbox , * ebox )
612
690
# Removing Zeros from coordinates
613
691
cam_coords = np .dot (inter_conv , coord ) * depth_roi .flatten () / 1000.0
692
+ self .roi_depth_np = cam_coords
614
693
# Removing outliers from Z coordinates. top and bottoom 0.5 percentile of valid depth
615
694
try :
616
695
valid_cam_coords = np .delete (cam_coords , np .where (cam_coords [2 , :] == 0.0 ), axis = 1 )
@@ -637,19 +716,8 @@ def calculate_errors(self):
637
716
subsampled_pixels = np .array (subsampled_pixels ).transpose ()
638
717
sub_points3D = np .dot (inter_conv , subsampled_pixels ) * subsampled_pixels_depth .flatten () / 1000.0 # [x, y, z]
639
718
sub_points3D = sub_points3D .transpose ()
640
- # sc._offsets3d = (sub_points3D[:, 0], sub_points3D[:, 1], sub_points3D[:, 2]) #3D Plot
641
719
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
- #
647
720
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)
653
721
plane_offset_error = 0
654
722
gt_offset_error = 0
655
723
planeR_ms_offset_rror = 0
@@ -704,7 +772,10 @@ def calculate_errors(self):
704
772
return True
705
773
706
774
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 )
708
779
if not self .calculate_errors ():
709
780
return
710
781
0 commit comments