99from PyQt5 .QtWidgets import QDialog , QAbstractSpinBox
1010import os
1111import time
12+ from matplotlib import pyplot as plt
1213
1314colorMode = QtGui .QImage .Format_RGB888
1415try :
1718 colorMode = QtGui .QImage .Format_RGB888
1819
1920CSV_HEADER = "TimeStamp,MxID,RealDistance,DetectedDistance,planeFitMSE,gtPlaneMSE,planeFitRMSE," \
20- "gtPlaneRMSE,fillRate,Result,Side"
21+ "gtPlaneRMSE,fillRate,pixelsNo, Result,Side"
2122mx_id = None
2223product = None
2324inter_conv = None
2627class Ui_DepthTest (object ):
2728 def setupUi (self , DepthTest ):
2829 DepthTest .setObjectName ("DepthTest" )
29- DepthTest .resize (1074 , 696 )
30+ DepthTest .resize (1074 , 723 )
31+ font = QtGui .QFont ()
32+ font .setPointSize (14 )
33+ DepthTest .setFont (font )
3034 self .centralwidget = QtWidgets .QWidget (DepthTest )
3135 self .centralwidget .setObjectName ("centralwidget" )
3236 self .l_info = QtWidgets .QLabel (self .centralwidget )
33- self .l_info .setGeometry (QtCore .QRect (30 , 270 , 221 , 331 ))
37+ self .l_info .setGeometry (QtCore .QRect (20 , 330 , 221 , 351 ))
3438 font = QtGui .QFont ()
3539 font .setPointSize (18 )
3640 self .l_info .setFont (font )
@@ -41,7 +45,7 @@ def setupUi(self, DepthTest):
4145"}" )
4246 self .l_info .setObjectName ("l_info" )
4347 self .l_result = QtWidgets .QLabel (self .centralwidget )
44- self .l_result .setGeometry (QtCore .QRect (110 , 230 , 101 , 51 ))
48+ self .l_result .setGeometry (QtCore .QRect (110 , 280 , 101 , 51 ))
4549 font = QtGui .QFont ()
4650 font .setPointSize (30 )
4751 self .l_result .setFont (font )
@@ -57,13 +61,13 @@ def setupUi(self, DepthTest):
5761 self .l_test .setFont (font )
5862 self .l_test .setObjectName ("l_test" )
5963 self .l_lidar = QtWidgets .QLabel (self .centralwidget )
60- self .l_lidar .setGeometry (QtCore .QRect (270 , 300 , 71 , 31 ))
64+ self .l_lidar .setGeometry (QtCore .QRect (270 , 350 , 71 , 31 ))
6165 font = QtGui .QFont ()
6266 font .setPointSize (18 )
6367 self .l_lidar .setFont (font )
6468 self .l_lidar .setObjectName ("l_lidar" )
6569 self .l_fill_rate = QtWidgets .QLabel (self .centralwidget )
66- self .l_fill_rate .setGeometry (QtCore .QRect (270 , 350 , 71 , 31 ))
70+ self .l_fill_rate .setGeometry (QtCore .QRect (270 , 400 , 71 , 31 ))
6771 self .l_fill_rate .setSizeIncrement (QtCore .QSize (0 , 0 ))
6872 font = QtGui .QFont ()
6973 font .setFamily ("Noto Sans" )
@@ -72,7 +76,7 @@ def setupUi(self, DepthTest):
7276 self .l_fill_rate .setFont (font )
7377 self .l_fill_rate .setObjectName ("l_fill_rate" )
7478 self .l_gt_plane_rmse = QtWidgets .QLabel (self .centralwidget )
75- self .l_gt_plane_rmse .setGeometry (QtCore .QRect (270 , 400 , 91 , 31 ))
79+ self .l_gt_plane_rmse .setGeometry (QtCore .QRect (270 , 450 , 91 , 31 ))
7680 font = QtGui .QFont ()
7781 font .setPointSize (18 )
7882 self .l_gt_plane_rmse .setFont (font )
@@ -105,23 +109,23 @@ def setupUi(self, DepthTest):
105109 self .preview_video .setGeometry (QtCore .QRect (410 , 30 , 640 , 480 ))
106110 self .preview_video .setObjectName ("preview_video" )
107111 self .l_plane_fit_mse = QtWidgets .QLabel (self .centralwidget )
108- self .l_plane_fit_mse .setGeometry (QtCore .QRect (270 , 450 , 91 , 31 ))
112+ self .l_plane_fit_mse .setGeometry (QtCore .QRect (270 , 500 , 91 , 31 ))
109113 font = QtGui .QFont ()
110114 font .setPointSize (18 )
111115 self .l_plane_fit_mse .setFont (font )
112116 self .l_plane_fit_mse .setObjectName ("l_plane_fit_mse" )
113117 self .l_gt_plane_mse = QtWidgets .QLabel (self .centralwidget )
114- self .l_gt_plane_mse .setGeometry (QtCore .QRect (270 , 500 , 91 , 31 ))
118+ self .l_gt_plane_mse .setGeometry (QtCore .QRect (270 , 550 , 91 , 31 ))
115119 font = QtGui .QFont ()
116120 font .setPointSize (18 )
117121 self .l_gt_plane_mse .setFont (font )
118122 self .l_gt_plane_mse .setObjectName ("l_gt_plane_mse" )
119- self .l_gt_plane_mse_2 = QtWidgets .QLabel (self .centralwidget )
120- self .l_gt_plane_mse_2 .setGeometry (QtCore .QRect (270 , 550 , 91 , 31 ))
123+ self .l_plane_fit_rmse = QtWidgets .QLabel (self .centralwidget )
124+ self .l_plane_fit_rmse .setGeometry (QtCore .QRect (270 , 600 , 91 , 31 ))
121125 font = QtGui .QFont ()
122126 font .setPointSize (18 )
123- self .l_gt_plane_mse_2 .setFont (font )
124- self .l_gt_plane_mse_2 .setObjectName ("l_gt_plane_mse_2 " )
127+ self .l_plane_fit_rmse .setFont (font )
128+ self .l_plane_fit_rmse .setObjectName ("l_plane_fit_rmse " )
125129 self .board_group = QtWidgets .QGroupBox (self .centralwidget )
126130 self .board_group .setGeometry (QtCore .QRect (410 , 520 , 151 , 131 ))
127131 self .board_group .setObjectName ("board_group" )
@@ -137,19 +141,28 @@ def setupUi(self, DepthTest):
137141 self .r_center .setChecked (True )
138142 self .r_center .setObjectName ("r_center" )
139143 self .options_group = QtWidgets .QGroupBox (self .centralwidget )
140- self .options_group .setGeometry (QtCore .QRect (900 , 520 , 151 , 131 ))
144+ self .options_group .setGeometry (QtCore .QRect (890 , 520 , 161 , 131 ))
141145 self .options_group .setObjectName ("options_group" )
142146 self .c_lrcheck = QtWidgets .QCheckBox (self .options_group )
143147 self .c_lrcheck .setGeometry (QtCore .QRect (10 , 30 , 97 , 26 ))
144148 self .c_lrcheck .setChecked (True )
145149 self .c_lrcheck .setObjectName ("c_lrcheck" )
146150 self .c_extended = QtWidgets .QCheckBox (self .options_group )
147- self .c_extended .setGeometry (QtCore .QRect (10 , 90 , 97 , 26 ))
151+ self .c_extended .setGeometry (QtCore .QRect (10 , 90 , 121 , 26 ))
148152 self .c_extended .setObjectName ("c_extended" )
149153 self .c_subpixel = QtWidgets .QCheckBox (self .options_group )
150- self .c_subpixel .setGeometry (QtCore .QRect (10 , 60 , 97 , 26 ))
154+ self .c_subpixel .setGeometry (QtCore .QRect (10 , 60 , 111 , 26 ))
151155 self .c_subpixel .setChecked (True )
152156 self .c_subpixel .setObjectName ("c_subpixel" )
157+ self .l_pixels_no = QtWidgets .QLabel (self .centralwidget )
158+ self .l_pixels_no .setGeometry (QtCore .QRect (270 , 650 , 91 , 31 ))
159+ font = QtGui .QFont ()
160+ font .setPointSize (18 )
161+ self .l_pixels_no .setFont (font )
162+ self .l_pixels_no .setObjectName ("l_pixels_no" )
163+ self .c_matplot = QtWidgets .QCheckBox (self .centralwidget )
164+ self .c_matplot .setGeometry (QtCore .QRect (110 , 230 , 111 , 31 ))
165+ self .c_matplot .setObjectName ("c_matplot" )
153166 DepthTest .setCentralWidget (self .centralwidget )
154167 self .statusbar = QtWidgets .QStatusBar (DepthTest )
155168 self .statusbar .setObjectName ("statusbar" )
@@ -171,7 +184,8 @@ def retranslateUi(self, DepthTest):
171184"gtPlaneRMSE:<br>\n "
172185"planeFitMSE:<br>\n "
173186"gtPlaneMSE:<br>\n "
174- "planeFitRMSE:</span></p>" ))
187+ "planeFitRMSE:<br>\n "
188+ "pixelsNo:</span></p>" ))
175189 self .b_start .setText (_translate ("DepthTest" , "Start" ))
176190 self .l_test .setText (_translate ("DepthTest" , "Depth Test" ))
177191 self .l_lidar .setText (_translate ("DepthTest" , "-" ))
@@ -182,7 +196,7 @@ def retranslateUi(self, DepthTest):
182196 self .l_sensor .setText (_translate ("DepthTest" , "-" ))
183197 self .l_plane_fit_mse .setText (_translate ("DepthTest" , "-" ))
184198 self .l_gt_plane_mse .setText (_translate ("DepthTest" , "-" ))
185- self .l_gt_plane_mse_2 .setText (_translate ("DepthTest" , "-" ))
199+ self .l_plane_fit_rmse .setText (_translate ("DepthTest" , "-" ))
186200 self .board_group .setTitle (_translate ("DepthTest" , "board_side" ))
187201 self .r_left .setText (_translate ("DepthTest" , "Left" ))
188202 self .r_right .setText (_translate ("DepthTest" , "Right" ))
@@ -191,6 +205,8 @@ def retranslateUi(self, DepthTest):
191205 self .c_lrcheck .setText (_translate ("DepthTest" , "lrcheck" ))
192206 self .c_extended .setText (_translate ("DepthTest" , "extended" ))
193207 self .c_subpixel .setText (_translate ("DepthTest" , "subpixel" ))
208+ self .l_pixels_no .setText (_translate ("DepthTest" , "-" ))
209+ self .c_matplot .setText (_translate ("DepthTest" , "Matplot" ))
194210
195211
196212class Camera :
@@ -202,7 +218,7 @@ def __init__(self, lrcheck, subpixel, extended):
202218 'OV9282' : dai .MonoCameraProperties .SensorResolution .THE_800_P
203219 }
204220 self .device = dai .Device ()
205- print (self .device .getDeviceInfo ().getXLinkDeviceDesc ())
221+ # print(self.device.getDeviceInfo().getXLinkDeviceDesc())
206222 sensors = self .device .getCameraSensorNames ()
207223 mono_resolution = cam_res [sensors [dai .CameraBoardSocket .LEFT ]]
208224 if mono_resolution is dai .MonoCameraProperties .SensorResolution .THE_400_P :
@@ -233,6 +249,7 @@ def __init__(self, lrcheck, subpixel, extended):
233249 mono_right .setBoardSocket (dai .CameraBoardSocket .RIGHT )
234250
235251 stereo .initialConfig .setConfidenceThreshold (200 )
252+ stereo .initialConfig .setMedianFilter (dai .MedianFilter .KERNEL_3x3 )
236253 stereo .setDefaultProfilePreset (dai .node .StereoDepth .PresetMode .HIGH_DENSITY )
237254 stereo .setRectifyEdgeFillColor (0 ) # black, to better see the cutout
238255 stereo .initialConfig .setMedianFilter (dai .StereoDepthProperties .MedianFilter .MEDIAN_OFF )
@@ -477,6 +494,7 @@ class Application(QtWidgets.QMainWindow):
477494 def __init__ (self ):
478495 super ().__init__ ()
479496 # DepthTest = QtWidgets.QMainWindow()
497+ self .pixels_no = 0
480498 self .fill_rate = None
481499 self .gt_plane_rmse = None
482500 self .plane_fit_rmse = None
@@ -506,6 +524,22 @@ def __init__(self):
506524 self .average_error = None
507525 self .set_result ('' )
508526 self .z_distance = 0
527+ self .plot_fit_plane = None
528+
529+ def set_plot (self ):
530+ # Plot Setup
531+ plt .ion ()
532+ x , y , z = [], [], []
533+ fig = plt .figure ()
534+ self .ax = fig .add_subplot (111 , projection = '3d' )
535+ self .sc = self .ax .scatter (x , y , z )
536+ self .ax .set_xlabel ('x' )
537+ self .ax .set_ylabel ('y' )
538+ self .ax .set_zlabel ('z' )
539+ self .ax .set_zlim (- 1 , 5 )
540+ self .ax .set_xlim (- 0.3 , 0.3 )
541+ self .ax .set_ylim (- 0.3 , 0.3 )
542+ self .plot_fit_plane = None
509543
510544 def set_result (self , result ):
511545 self .ui .l_result .setText (result )
@@ -543,7 +577,7 @@ def button_event(self):
543577
544578 def save_csv (self ):
545579 path = os .path .realpath (__file__ ).rsplit ('/' , 1 )[0 ] + '/depth_result/' + str (product ) + '.csv'
546- print (path )
580+ # print(path)
547581 if os .path .exists (path ):
548582 file = open (path , 'a' )
549583 else :
@@ -560,14 +594,15 @@ def save_csv(self):
560594 side = 'center'
561595 file .write (f' { int (time .time ())} ,{ mx_id } ,{ self .true_distance } ,{ self .z_distance } ,{ self .plane_fit_mse } ,\
562596 { self .gt_plane_mse } ,{ self .plane_fit_rmse } ,{ self .gt_plane_rmse } ,{ self .fill_rate } ,\
563- { self .ui .l_result .text ()} ,{ side } \n ' )
597+ { self .pixels_no } , { self . ui .l_result .text ()} ,{ side } \n ' )
564598 file .close ()
565599
566600 def calculate_errors (self ):
567601 depth_frame = self .scene .get_frame ().get_depth_frame ()
568602 sbox , ebox = self .scene .get_frame ().get_roi ()
569603 if sbox is None or ebox is None :
570604 return False
605+ self .pixels_no = (ebox [0 ]- sbox [0 ])* (ebox [1 ]- sbox [1 ])
571606 depth_roi = depth_frame [sbox [1 ]:ebox [1 ], sbox [0 ]:ebox [0 ]]
572607 coord = pixel_coord_np (* sbox , * ebox )
573608 # Removing Zeros from coordinates
@@ -634,6 +669,34 @@ def calculate_errors(self):
634669 flatRoi = depth_roi .flatten ()
635670 sampledPixels = np .delete (flatRoi , np .where (flatRoi == 0 ))
636671 self .fill_rate = 100 * sampledPixels .shape [0 ] / totalPixels
672+
673+ if self .ui .c_matplot .isChecked ():
674+ if self .plot_fit_plane is None :
675+ self .set_plot ()
676+ self .sc ._offsets3d = (sub_points3D [:, 0 ], sub_points3D [:, 1 ], sub_points3D [:, 2 ]) # 3D Plot
677+ # Fitting the plane to the subsampled RPOI points
678+ maxx = np .max (sub_points3D [:, 0 ])
679+ maxy = np .max (sub_points3D [:, 1 ])
680+ minx = np .min (sub_points3D [:, 0 ])
681+ miny = np .min (sub_points3D [:, 1 ])
682+
683+ d = - np .array ([0.0 , 0.0 , c ]).dot (normal )
684+ xx , yy = np .meshgrid ([minx , maxx ], [miny , maxy ])
685+ z = (- normal [0 ] * xx - normal [1 ] * yy - d ) * 1. / normal [2 ]
686+
687+ # Plotting the fit plane
688+ if self .plot_fit_plane is None :
689+ self .plot_fit_plane = self .ax .plot_surface (xx , yy , z , alpha = 0.2 )
690+ else :
691+ fit_plane_corners = np .vstack ((xx .flatten (), yy .flatten (), z .flatten (), np .ones ((1 , 4 ))))
692+ temp_col3 = fit_plane_corners [:, 2 ].copy ()
693+ fit_plane_corners [:, 2 ] = fit_plane_corners [:, 3 ]
694+ fit_plane_corners [:, 3 ] = temp_col3
695+ self .plot_fit_plane ._vec = fit_plane_corners
696+ plt .draw ()
697+ else :
698+ self .plot_fit_plane = None
699+ plt .close ()
637700 return True
638701
639702 def timer_event (self ):
@@ -679,8 +742,8 @@ def timer_event(self):
679742 self .ui .l_gt_plane_rmse .setText (f'{ self .max_error } ' )
680743 self .ui .l_plane_fit_mse .setText (f'{ self .plane_fit_mse } ' )
681744 self .ui .l_gt_plane_mse .setText (f'{ self .gt_plane_mse } ' )
682- self .ui .l_plane_fit_mse .setText (f'{ self .plane_fit_mse } ' )
683-
745+ self .ui .l_plane_fit_rmse .setText (f'{ self .plane_fit_rmse } ' )
746+ self . ui . l_pixels_no . setText ( f' { self . pixels_no } ' )
684747 if self .true_distance <= 1 :
685748 error_threshold = 0.03
686749 elif self .true_distance >= 2 :
0 commit comments