@@ -103,7 +103,7 @@ def preprocess(self, img = None):
103103
104104 # init params of the inverse
105105 if self .matrix_dir is None :
106- self .fit_plane_init ()
106+ self .fit_plane_init_old ()
107107
108108 x0 , y0 , x1 , y1 = self .rect
109109 if len (img .shape ) > 2 :
@@ -232,7 +232,7 @@ def fit_plane_init(self):
232232 self .cam_matrix = np .array ([[650 ,0 ,self .frame_size [0 ]/ 2 ],[0 ,650 ,self .frame_size [1 ]/ 2 ],[0 ,0 ,1 ]], dtype = np .float32 )
233233 self .cam_distort = np .array ([0 ,0 ,0 ,0 ,0 ],dtype = np .float32 )
234234
235- x0 ,y0 ,x1 ,y1 = 0 ,0 ,self .frame_size [1 ],self .frame_size [0 ] #self.rect
235+ x0 ,y0 ,x1 ,y1 = 0 ,0 ,self .frame_size [0 ],self .frame_size [1 ] #self.rect
236236 h ,w = y1 - y0 , x1 - x0
237237 x_grid = np .arange (x0 , x1 , 1 )
238238 y_grid = np .arange (y0 , y1 , 1 )
@@ -295,41 +295,62 @@ def convert_roi_to_points(self, img, point_num = 30, step_size = 1, roi_rect = N
295295 "converting roi to pts in XYZ - Nx3 array. point_num - is the target point number"
296296
297297 # init params of the inverse
298- if self .matrix_dir is None :
298+ if self .matrix_xyz is None : # do not use mtrix_dir - initialized before
299299 self .fit_plane_init ()
300300
301301 # deal iwth different rect options
302302 roi_rect = self .rect if roi_rect is None else roi_rect
303+ x0 , y0 , x1 , y1 = roi_rect
304+
305+ # make rectangle
306+ h ,w = y1 - y0 , x1 - x0
307+ self .rect_3d = [[- w ,- h ,0 ],[w ,- h ,0 ],[w ,h ,0 ],[- w ,h ,0 ],[- w ,- h ,0 ]]
303308
304309 # extract roi - must be compatible with image dimensions
305- n ,m = img .shape [:2 ]
306- img_roi_mask = np .zeros ((n ,m ), dtype = np .bool_ )
307- x0 , y0 , x1 , y1 = roi_rect
308- img_roi_mask [y0 :y1 ,x0 :x1 ] = 1
309- valid_bool = img_roi_mask > 0
310- valid_bool = valid_bool .flatten ()
310+ # n,m = img.shape[:2]
311+ # img_roi_mask = np.zeros((n,m), dtype = np.bool_)
312+ # img_roi_mask[y0:y1,x0:x1] = True
313+ # valid_bool = img_roi_mask > 0 & img > 0
314+
315+ # check if roi is valid
316+ x_grid = np .arange (x0 , x1 , 1 )
317+ y_grid = np .arange (y0 , y1 , 1 )
318+ x , y = np .meshgrid (x_grid , y_grid )
319+ flat_indices = np .ravel_multi_index ((y , x ), img .shape [:2 ]).reshape ((- 1 ,1 ))
320+
321+ # valid under mask
322+ #valid_bool = img.flat[flat_indices] > 0
323+ #ii = flat_indices[valid_bool]
324+ img_roi = img [y0 :y1 ,x0 :x1 ].astype (np .float32 ).reshape ((- 1 ,1 ))
325+ valid_bool = img_roi > 0 # valid pixels in the roi
326+ ii = np .flatnonzero (valid_bool )
327+
328+ #valid_bool = valid_bool.flatten()
311329 #log.info(f'Timing : 1')
312330
313331 # rect to show
314- h ,w = y1 - y0 , x1 - x0
315- self .rect_3d = [[- w ,- h ,0 ],[w ,- h ,0 ],[w ,h ,0 ],[- w ,h ,0 ],[- w ,- h ,0 ]]
332+ # h,w = y1-y0, x1-x0
333+ # self.rect_3d = [[-w,-h,0],[w,-h,0],[w,h,0],[-w,h,0],[-w,-h,0]]
316334
317335 # all non valid
318- ii = np .where (valid_bool )[0 ]
336+ #ii = np.where(valid_bool)[0]
337+
319338 valid_point_num = len (ii )
320339 if valid_point_num < 5 :
321340 return None
322341 step_size = np .maximum (step_size , np .int32 (valid_point_num / point_num ))
323342 ii = ii [::step_size ]
324343
325344 # plane params - using only valid
326- z = img .flat [ii ].reshape ((- 1 ,1 ))
327- xyz_matrix = self .matrix_dir [ii ,:]
345+ #z = img.flat[ii].reshape((-1,1))
346+ z = img_roi [ii ].reshape ((- 1 ,1 ))
347+ jj = flat_indices [ii ].flatten ()
348+ xyz_matrix = self .matrix_dir [jj ,:]
328349 xyz_matrix [:,:3 ] = xyz_matrix [:,:3 ]* z # keep 1 intact
329350
330351 #self.plane_center = xyz_center.flatten()
331352 self .matrix_xyz = xyz_matrix
332- self .matrix_index = ii
353+ self .matrix_index = jj
333354
334355 return xyz_matrix
335356
@@ -402,6 +423,49 @@ def convert_roi_to_points_old(self, img_roi, point_num = 30, step_size = 1):
402423
403424 def fit_plane_svd (self , img_roi ):
404425 "estimates mean and std of the plane fit"
426+
427+ # roi converted to points with step size on the grid
428+ xyz_matrix = self .convert_roi_to_points (img_roi , point_num = 250 , step_size = 1 )
429+ #xyz_matrix = self.convert_roi_to_points_old(img_roi, point_num = 1e4, step_size = 1)
430+
431+ # substract mean
432+ xyz_center = xyz_matrix [:,:3 ].mean (axis = 0 )
433+ xyz_matrix = xyz_matrix - xyz_center
434+ #log.info(f'Timing : 2')
435+
436+ # mtrx_dir = np.hstack((self.matrix_dir[valid_bool,0]*z,self.matrix_dir[valid_bool,1]*z,z*0+1))
437+ # mtrx_inv = np.linalg.pinv(mtrx_dir)
438+ # #mtrx_inv = self.matrix_inv[:,valid_bool]
439+ # plane_params = np.dot(mtrx_inv,z)
440+
441+ # decimate to make it run faster reduce size of the grid for speed. 1000 pix - 30x30 - step 1, 10000 pix - step=3
442+ #roi_area = n*m
443+ #step_size = int(np.sqrt(roi_area)/7) if roi_area > 1000 else 1
444+
445+ # using svd to make the fit
446+ U , S , Vh = np .linalg .svd (xyz_matrix , full_matrices = True )
447+ ii = np .argmin (S )
448+ vnorm = Vh [ii ,:]
449+ #log.info(f'Timing : 3')
450+
451+ # keep orientation
452+ plane_params = vnorm * np .sign (vnorm [2 ])
453+
454+ # estimate error
455+ err = np .dot (xyz_matrix ,plane_params )
456+ #z_est = z + err + xyz_center[2]
457+
458+ img_mean = xyz_center [2 ] #z_est.mean()
459+ img_std = err .std ()
460+ self .plane_params = plane_params [:3 ].flatten ()
461+ self .plane_center = xyz_center .flatten ()
462+
463+ #log.info(f'Plane : {self.plane_params}, error {img_std:.3f}, step {step_size}')
464+
465+ return img_mean , img_std
466+
467+ def fit_plane_svd_old (self , img_roi ):
468+ "estimates mean and std of the plane fit"
405469 # n,m = img_roi.shape[:2]
406470 # img_roi = img_roi.reshape((-1,1))
407471 # valid_bool = img_roi > 0
@@ -459,7 +523,7 @@ def fit_plane_svd(self, img_roi):
459523 #log.info(f'Plane : {self.plane_params}, error {img_std:.3f}, step {step_size}')
460524
461525 return img_mean , img_std
462-
526+
463527 def fit_plane_with_outliers (self , img_roi ):
464528 "computes normal for the specifric roi and evaluates error. Do it twice to reject outliers"
465529
@@ -529,8 +593,8 @@ def fit_plane_ransac(self, img_roi):
529593 """
530594 #log.info('Fit ransac: ...')
531595 # roi converted to points with step size on the grid
532- # xyz_matrix = self.convert_roi_to_points_old(img_roi, point_num = 250, step_size = 1)
533- xyz_matrix = self .convert_roi_to_points (img_roi , point_num = 250 , step_size = 1 )
596+ xyz_matrix = self .convert_roi_to_points_old (img_roi , point_num = 250 , step_size = 1 )
597+ # xyz_matrix = self.convert_roi_to_points(img_roi, point_num = 250, step_size = 1)
534598 if xyz_matrix is None :
535599 log .error ('No points in the ROI' )
536600 return 0 , 0
@@ -731,10 +795,10 @@ def find_planes(self, img):
731795 if detect_type == 'P' :
732796 img_mean , img_std = self .fit_plane_svd (img )
733797 elif detect_type == 'O' :
734- img_mean , img_std = self .fit_plane_svd (img_roi )
798+ img_mean , img_std = self .fit_plane_svd_old (img_roi )
735799 #img_mean, img_std = self.fit_plane_with_outliers(img_roi)
736800 elif detect_type == 'R' :
737- img_mean , img_std = self .fit_plane_ransac (img )
801+ img_mean , img_std = self .fit_plane_ransac (img_roi )
738802 elif detect_type == 'G' :
739803 img_mean , img_std = self .fit_plane_ransac_and_grow (img )
740804
0 commit comments