Skip to content

Commit fbc690b

Browse files
committed
plane detector starting to work
1 parent 9ce2ae1 commit fbc690b

File tree

2 files changed

+85
-21
lines changed

2 files changed

+85
-21
lines changed

wrappers/python/applications/planes/src/plane_detector.py

Lines changed: 84 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -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

wrappers/python/applications/planes/test/test_plane_detector.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -424,7 +424,7 @@ def show_mask(self, img):
424424
"draw image mask"
425425

426426
# deal with black and white
427-
img_show = img #np.uint8(img) #.copy()
427+
img_show = np.uint8(img) #.copy()
428428
if len(img.shape) < 3:
429429
img_show = cv.applyColorMap(img_show, cv.COLORMAP_JET)
430430

0 commit comments

Comments
 (0)