1+ import pykitti
2+ import numpy as np
3+ import argparse
4+ import os
5+ import cv2
6+ import open3d as o3d
7+ import copy
8+ # import matplotlib
9+ # matplotlib.use('agg')
10+ from matplotlib import pyplot as plt
11+ from tools import *
12+ from scipy .spatial .ckdtree import cKDTree
13+ from fps_v1 import FPS
14+
15+
16+ os .chdir (os .path .dirname (__file__ ))
17+
18+ def str2bool (s :str ) -> bool :
19+ if s .isdigit ():
20+ if float (s ) > 0 :
21+ return True
22+ else :
23+ return False
24+ if s .lower () == "false" :
25+ return False
26+ else :
27+ return True
28+
29+ def options ():
30+ parser = argparse .ArgumentParser ()
31+ kitti_parser = parser .add_argument_group ()
32+ kitti_parser .add_argument ("--base_dir" ,type = str ,default = "/data/DATA/data_odometry/dataset/" )
33+ kitti_parser .add_argument ("--seq" ,type = int ,default = 0 ,choices = [i for i in range (11 )])
34+ kitti_parser .add_argument ("--index_i" ,type = int ,default = 0 )
35+ kitti_parser .add_argument ("--index_j" ,type = int ,default = 1 )
36+
37+ io_parser = parser .add_argument_group ()
38+ io_parser .add_argument ("--Twc_file" ,type = str ,default = "../Twc.txt" )
39+ io_parser .add_argument ("--Twl_file" ,type = str ,default = "../Twl.txt" )
40+
41+ arg_parser = parser .add_argument_group ()
42+ arg_parser .add_argument ("--tsl_perturb" ,type = float ,nargs = 3 ,default = [0.1 ,- 0.15 ,0.1 ])
43+ arg_parser .add_argument ("--rot_perturb" ,type = float ,nargs = 3 ,default = [0 ,0 ,0 ])
44+ arg_parser .add_argument ("--fps_sample" ,type = int ,default = - 1 )
45+ arg_parser .add_argument ("--pixel_corr_dist" ,type = float ,default = 3 )
46+ arg_parser .add_argument ("--view" ,type = str2bool ,default = True )
47+ args = parser .parse_args ()
48+ args .seq_id = "%02d" % args .seq
49+ return args
50+
51+
52+ def drawcorrpoints (img1 ,img2 ,pts1 ,pts2 ):
53+ img1 = cv2 .cvtColor (img1 ,cv2 .COLOR_GRAY2BGR )
54+ img2 = cv2 .cvtColor (img2 ,cv2 .COLOR_GRAY2BGR )
55+ for pt1 ,pt2 in zip (pts1 ,pts2 ):
56+ color = tuple (np .random .randint (0 ,255 ,3 ).tolist ())
57+ img1 = cv2 .circle (img1 ,tuple (pt1 ),5 ,color ,- 1 )
58+ img2 = cv2 .circle (img2 ,tuple (pt2 ),5 ,color ,- 1 )
59+ return img1 ,img2
60+
61+ def draw3corrpoints (img1 ,img2 ,pts11 ,pts12 ,pts2 ):
62+ img1 = cv2 .cvtColor (img1 ,cv2 .COLOR_GRAY2BGR )
63+ img2 = cv2 .cvtColor (img2 ,cv2 .COLOR_GRAY2BGR )
64+ for pt11 ,pt12 ,pt2 in zip (pts11 ,pts12 ,pts2 ):
65+ color = tuple (np .random .randint (0 ,255 ,3 ).tolist ())
66+ img1 = cv2 .circle (img1 ,tuple (pt11 ),5 ,color ,1 )
67+ img1 = cv2 .circle (img1 ,tuple (pt12 ),5 ,color ,1 )
68+ img2 = cv2 .circle (img2 ,tuple (pt2 ),5 ,color ,1 )
69+ return img1 ,img2
70+
71+ def compute_orb_desc (img :np .ndarray ):
72+ """compute orb descriptors
73+
74+ Args:
75+ img (np.ndarray): HxW
76+
77+ Returns:
78+ _type_: keypoints, descriptors
79+ """
80+ if len (img .shape ) == 3 :
81+ img = cv2 .cvtColor (img , cv2 .COLOR_BGR2GRAY )
82+ orb = cv2 .ORB_create (nfeatures = 1000 )
83+ kp , desc = orb .detectAndCompute (img , None )
84+ return kp , desc
85+
86+ if __name__ == "__main__" :
87+ args = options ()
88+ augT = toMat (args .rot_perturb , args .tsl_perturb )
89+ print ("augT:\n {}" .format (augT ))
90+ dataStruct = pykitti .odometry (args .base_dir , args .seq_id )
91+ calibStruct = dataStruct .calib
92+ extran = calibStruct .T_cam0_velo # [4,4]
93+ print ("GT TCL:\n {}" .format (extran ))
94+ print ("GT TCL Rvec:{}\n tvec:{}" .format (* toVec (extran )))
95+ aug_extran = augT @ extran
96+ intran = calibStruct .K_cam0
97+ src_pcd_arr = dataStruct .get_velo (args .index_i )[:,:3 ] # [N, 3]
98+ tgt_pcd_arr = dataStruct .get_velo (args .index_j )[:,:3 ] # [N, 3]
99+ src_img = np .array (dataStruct .get_cam0 (args .index_i )) # [H, W, 3]
100+ tgt_img = np .array (dataStruct .get_cam0 (args .index_j )) # [H, W, 3]
101+ src_pose = dataStruct .poses [args .index_i ]
102+ tgt_pose = dataStruct .poses [args .index_j ]
103+ camera_motion :np .ndarray = tgt_pose @ inv_pose (src_pose )
104+ orb = cv2 .ORB_create (nfeatures = 1000 )
105+ src_kp , src_desc = compute_orb_desc (src_img )
106+ tgt_kp , tgt_desc = compute_orb_desc (tgt_img )
107+ bf = cv2 .BFMatcher (cv2 .NORM_HAMMING , crossCheck = True )
108+ matches = bf .match (src_desc ,tgt_desc )
109+ src_matched_pts = []
110+ tgt_matched_pts = []
111+ for match in matches :
112+ src_matched_pts .append (src_kp [match .queryIdx ].pt )
113+ tgt_matched_pts .append (tgt_kp [match .trainIdx ].pt )
114+
115+ src_matched_pts = np .array (src_matched_pts ) # [N, 2]
116+ tgt_matched_pts = np .array (tgt_matched_pts )
117+
118+ src_pcd_camcoord = nptran (src_pcd_arr , extran )
119+ proj_src_pcd , src_rev = npproj (src_pcd_camcoord , np .eye (4 ), intran , src_img .shape )
120+ src_2d_kdtree = cKDTree (proj_src_pcd , leafsize = 30 )
121+ src_dist , src_pcd_query = src_2d_kdtree .query (src_matched_pts , 1 , eps = 1e-4 , p = 1 )
122+
123+ src_dist_rev = src_dist < args .pixel_corr_dist
124+ src_matched_pts = src_matched_pts [src_dist_rev ]
125+ tgt_matched_pts = tgt_matched_pts [src_dist_rev ]
126+ src_pcd_query = src_pcd_query [src_dist_rev ]
127+
128+ src2tgt_pcd_arr = nptran (src_pcd_camcoord [src_rev ][src_pcd_query ], camera_motion )
129+ src2tgt_proj_pcd , src2tgt_proj_rev = npproj (src2tgt_pcd_arr , np .eye (4 ), intran , tgt_img .shape )
130+ src_matched_pts = src_matched_pts [src2tgt_proj_rev ]
131+ tgt_matched_pts = tgt_matched_pts [src2tgt_proj_rev ]
132+ tgt_matched_pts , src2tgt_proj_pcd , src_matched_pts = list (map (lambda arr : arr .astype (np .int32 ),[tgt_matched_pts , src2tgt_proj_pcd , src_matched_pts ]))
133+ if (args .fps_sample > 0 ):
134+ fps = FPS (tgt_matched_pts , n_samples = args .fps_sample )
135+ _ , fps_idx = fps .fit (True )
136+ else :
137+ fps_idx = np .arange (tgt_matched_pts .shape [0 ])
138+ draw_src_img , draw_tgt_img = drawcorrpoints (src_img , tgt_img , src_matched_pts [fps_idx ], tgt_matched_pts [fps_idx ])
139+ # draw_tgt_img, draw_src_img = draw3corrpoints(tgt_img, src_img, tgt_matched_pts[fps_idx], src2tgt_proj_pcd[fps_idx], src_matched_pts[fps_idx])
140+ plt .subplot (2 ,1 ,1 )
141+ plt .imshow (draw_src_img )
142+ plt .subplot (2 ,1 ,2 )
143+ plt .imshow (draw_tgt_img )
144+ plt .show ()
145+
0 commit comments