2222import cv2 as cv
2323
2424
25- #from scipy import interpolate
26-
2725 # importing common Use modules
2826sys .path .append (r'wrappers\python\applications\utils\src' )
2927from logger import log
@@ -53,7 +51,6 @@ def __init__(self, detect_type = 'p'):
5351 self .plane_center = None # tvec
5452 #self.corner_ind = [0, 10, 40, 50] # corner of the rectnagle for the projection
5553 self .rect_3d = None # roi but projected on 3D
56-
5754
5855 # params
5956 self .MIN_SPLIT_SIZE = 32
@@ -62,6 +59,17 @@ def __init__(self, detect_type = 'p'):
6259 # help variable
6360 self .ang_vec = np .zeros ((3 ,1 )) # help variable
6461
62+ def init_image (self , img = None ):
63+ "load image"
64+ if img is None :
65+ log .info ('No image provided' )
66+ return False
67+
68+ self .img = img
69+ h ,w = img .shape [:2 ]
70+ self .frame_size = (w ,h )
71+ return True
72+
6573 def init_roi (self , test_type = 1 ):
6674 "load the test case"
6775 roi = [0 ,0 ,self .frame_size [0 ],self .frame_size [1 ]]
@@ -152,33 +160,6 @@ def compute_img3d(self, img = None):
152160 self .img_xyz = imgXYZ
153161 return imgXYZ
154162
155- def detect_pose_in_chessboard (self ):
156- # chess board pose extimation
157- criteria = (cv .TERM_CRITERIA_EPS + cv .TERM_CRITERIA_MAX_ITER , 30 , 0.001 )
158- objp = np .zeros ((6 * 7 ,3 ), np .float32 )
159- objp [:,:2 ] = np .mgrid [0 :7 ,0 :6 ].T .reshape (- 1 ,2 )
160- axis = np .float32 ([[3 ,0 ,0 ], [0 ,3 ,0 ], [0 ,0 ,- 3 ]]).reshape (- 1 ,3 )
161- if len (self .img .shape ) > 2 :
162- gray = cv .cvtColor (self .img , cv .COLOR_BGR2GRAY )
163- else :
164- gray = self .img
165- flags_cv = cv .CALIB_CB_ADAPTIVE_THRESH + cv .CALIB_CB_FAST_CHECK #+ cv.CALIB_CB_NORMALIZE_IMAGE
166- ret , corners = cv .findChessboardCorners (gray , (7 ,6 ), flags = flags_cv )
167- #ret, corners = cv.findChessboardCornersSB(gray, (7,6))
168- if ret == True :
169- corners = cv .cornerSubPix (gray ,corners ,(11 ,11 ),(- 1 ,- 1 ),criteria )
170- else :
171- print ('Failed to find points' )
172- return np .zeros ((1 ,7 ))
173- # Find the rotation and translation vectors.
174- ret ,rvecs , tvecs = cv .solvePnP (objp , corners , self .cam_matrix , self .cam_distort )
175- # transfer to pose
176- R , _ = cv .Rodrigues (rvecs )
177- avec = rotationMatrixToEulerAngles (R )
178- pose = np .hstack ((tvecs .flatten (), avec .flatten (), 3 ))
179- print ('Chess pose : ' , pose )
180- return [pose ]
181-
182163 def check_error (self , xyz1_mtrx , vnorm ):
183164 "checking the error norm"
184165 err = np .dot (xyz1_mtrx , vnorm )
@@ -219,8 +200,6 @@ def convert_roi_to_points(self, img_roi, point_num = 30, step_size = 0):
219200 step_size = np .maximum (1 , np .int32 (valid_point_num / point_num ))
220201 ii = ii [::step_size ]
221202
222-
223-
224203 # plane params - using only valid
225204 z = img_roi [ii ]
226205 xyz_matrix = self .matrix_dir [ii ,:]
@@ -246,27 +225,6 @@ def convert_roi_to_points(self, img_roi, point_num = 30, step_size = 0):
246225 #self.plane_center = xyz_center.flatten()
247226
248227 return xyz_matrix
249-
250- def convert_roi_params_to_pose (self , roi_params ):
251- "converting params to the pose vector"
252- tvec = roi_params ['tvec' ].reshape ((1 ,- 1 ))
253- vnorm = roi_params ['vnorm' ] # 4x1 vector
254- #rvec = vnorm[:3].reshape((1,-1))
255- #rvec = rvec/np.linalg.norm(rvec)
256-
257- rvec = vnorm .flatten () #reshape((-1,1))
258- #rvec[3] = 0 # kill DC
259- rvec = rvec / np .linalg .norm (rvec )
260-
261- #R = Rot.from_quat(rvec).as_matrix()
262- #R = Rot.from_rotvec(rvec).as_matrix()
263- #avec = Rot.from_matrix(R).as_euler('zyx',degrees=True)
264- #self.ang_vec= avec
265-
266- levl = 0.1 * tvec [0 ,2 ]
267- pose_norm = np .hstack ((tvec , rvec .reshape ((1 ,- 1 )),[[levl ]]))
268- #log.info('roi to pose')
269- return pose_norm #.flatten()
270228
271229 def convert_plane_params (self , plane_equation ):
272230 "convert plane params to rvec"
@@ -279,7 +237,7 @@ def convert_plane_params(self, plane_equation):
279237 normal = plane_equation #np.array([plane_equation[0], plane_equation[1], plane_equation[2]])
280238 normal_norm = np .linalg .norm (normal )
281239 if normal_norm == 0 :
282- print ("Error: Zero norm for plane normal vector." )
240+ log . error ("Error: Zero norm for plane normal vector." )
283241 return None
284242 normal = normal / normal_norm
285243
@@ -300,13 +258,19 @@ def convert_plane_params(self, plane_equation):
300258
301259 return rvec
302260
303- def convert_plane_to_rvec (self , normal ):
304- # Convert plane normal to rotation vector
305- z_axis = np .array ([0 , 0 , 1 ])
306- rotation_matrix = cv .Rodrigues (np .cross (z_axis , normal ))[0 ]
307- rvec , _ = cv .Rodrigues (rotation_matrix )
308-
309- return rvec
261+ def convert_plane_params_to_pose (self , plane_params = None , plane_center = None ):
262+ "converting params of the plane to the pose vector"
263+
264+ plane_params = self .plane_params if plane_params is None else plane_params [:3 ].flatten ()
265+ plane_center = self .plane_center if plane_center is None else plane_center [:3 ].flatten ()
266+
267+ tvec = plane_center .reshape ((1 ,- 1 ))
268+ rvec = plane_params .reshape ((1 ,- 1 )) #reshape((-1,1))
269+ rvec = rvec / np .linalg .norm (rvec .flatten ())
270+
271+ pose_norm = np .hstack ((tvec , rvec ))
272+ #log.info('roi to pose')
273+ return pose_norm #.flatten()
310274
311275 def fit_plane_init (self ):
312276 "prepares data for real time fit a*x+b*y+c = z"
@@ -395,30 +359,6 @@ def fit_plane_svd(self, img_roi):
395359 #log.info(f'Plane : {self.plane_params}, error {img_std:.3f}, step {step_size}')
396360
397361 return img_mean , img_std
398-
399- def fit_plane (self , roi ):
400- "computes normal for the specifric roi and evaluates error"
401-
402- # roi converted to points with step size on the grid
403- xyz_matrix = self .convert_roi_to_points (roi , step_size = 0 )
404-
405- # using svd to make the fit
406- tvec = xyz_matrix [:,:3 ].mean (axis = 0 )
407- xyz1_matrix = xyz_matrix - tvec
408- U , S , Vh = np .linalg .svd (xyz_matrix , full_matrices = True )
409- ii = np .argmin (S )
410- vnorm = Vh [ii ,:]
411-
412- # keep orientation
413- vnorm = vnorm * np .sign (vnorm [2 ])
414-
415- # checking error
416- err_std = self .check_error (xyz_matrix , vnorm )
417- log .info ('Fit error : %s' % str (err_std ))
418-
419- # forming output
420- roi_params = {'roi' :roi , 'error' : err_std , 'tvec' : tvec , 'vnorm' :vnorm }
421- return roi_params
422362
423363 def fit_plane_with_outliers (self , img_roi ):
424364 "computes normal for the specifric roi and evaluates error. Do it twice to reject outliers"
@@ -603,12 +543,10 @@ def find_planes(self, img):
603543 "finds planes using different algo"
604544
605545 img_roi = self .preprocess (img )
606- detect_type = self .detect_type .upper ()
546+ detect_type = self .detect_type .upper ()
607547
608- img_mean , img_std = 0 ,0
609- if detect_type == 'T' :
610- img_mean , img_std = self .fit_plane (img_roi )
611- elif detect_type == 'P' :
548+ img_mean , img_std = 0 ,0
549+ if detect_type == 'P' :
612550 img_mean , img_std = self .fit_plane_svd (img_roi )
613551 elif detect_type == 'O' :
614552 img_mean , img_std = self .fit_plane_with_outliers (img_roi )
@@ -621,16 +559,15 @@ def find_planes(self, img):
621559 return True
622560
623561 def process_frame (self , img ):
624- "process the entire image image"
625-
626- img_roi = self .preprocess (img )
627- img3d = self .init_img3d (img_roi )
628- imgXYZ = self .compute_img3d (img_roi )
629- roip = self .fit_plane_with_outliers ()
630-
631- pose = self .convert_roi_params_to_pose (roip )
632- self .show_image_with_axis (img_roi , pose )
633- return self .rect
562+ "process the entire image and find the planes"
563+
564+ img_roi = self .preprocess (img )
565+ img3d = self .init_img3d (img_roi )
566+ imgXYZ = self .compute_img3d (img_roi )
567+ roim ,rois = self .fit_plane_with_outliers (img_roi )
568+ pose = self .convert_plane_params_to_pose ()
569+
570+ return pose
634571
635572if __name__ == '__main__' :
636573 #print(__doc__)
0 commit comments