88from message_filters import Subscriber , ApproximateTimeSynchronizer
99from cv_bridge import CvBridge
1010import time
11+ import os
12+ import yaml
1113
1214# Publisher imports:
1315from jsk_recognition_msgs .msg import BoundingBoxArray
@@ -24,16 +26,43 @@ class YoloNode():
2426 and return only detections from the current frame.
2527 """
2628
27- def __init__ (self ):
29+ def __init__ (self , camera_calib_file : str ):
2830 self .latest_image = None
2931 self .latest_lidar = None
3032 self .bridge = CvBridge ()
3133 self .camera_name = 'front'
3234 self .camera_front = (self .camera_name == 'front' )
3335 self .score_threshold = 0.4
3436 self .debug = True
35- # self.undistort_map1 = None
36- # self.undistort_map2 = None
37+
38+ # # 1) Load LiDAR-to-vehicle transform
39+ # self.T_l2v = np.array(T_l2v) if T_l2v is not None else np.array([
40+ # [0.99939639, 0.02547917, 0.023615, 1.1],
41+ # [-0.02530848, 0.99965156, -0.00749882, 0.03773583],
42+ # [-0.02379784, 0.00689664, 0.999693, 1.95320223],
43+ # [0.0, 0.0, 0.0, 1.0]
44+ # ])
45+
46+ # 2) Load camera intrinsics/extrinsics from YAML
47+ with open (camera_calib_file , 'r' ) as f :
48+ calib = yaml .safe_load (f )
49+
50+ # Expect structure:
51+ # cameras:
52+ # front:
53+ # K: [[...], [...], [...]]
54+ # D: [...]
55+ # T_l2c: [[...], ..., [...]]
56+ cam_cfg = calib ['cameras' ][self .camera_name ]
57+ self .K = np .array (cam_cfg ['K' ])
58+ self .D = np .array (cam_cfg ['D' ])
59+ self .T_l2c = np .array (cam_cfg ['T_l2c' ])
60+ self .T_l2v = np .array (cam_cfg ['T_l2v' ])
61+
62+ self .undistort_map1 = None
63+ self .undistort_map2 = None
64+ self .camera_front = (self .camera_name == 'front' )
65+
3766 self .initialize ()
3867
3968 def initialize (self ):
@@ -56,45 +85,6 @@ def initialize(self):
5685 self .pub = rospy .Publisher ('/yolo_boxes' , BoundingBoxArray , queue_size = 1 )
5786 rospy .loginfo ("YOLO node initialized and waiting for messages." )
5887
59- # Set camera intrinsic parameters based on camera
60- if self .camera_front :
61- self .K = np .array ([[684.83331299 , 0. , 573.37109375 ],
62- [0. , 684.60968018 , 363.70092773 ],
63- [0. , 0. , 1. ]])
64- self .D = np .array ([0.0 , 0.0 , 0.0 , 0.0 , 0.0 ])
65- else :
66- self .K = np .array ([[1.17625545e+03 , 0.00000000e+00 , 9.66432645e+02 ],
67- [0.00000000e+00 , 1.17514569e+03 , 6.08580326e+02 ],
68- [0.00000000e+00 , 0.00000000e+00 , 1.00000000e+00 ]])
69- self .D = np .array ([- 2.70136325e-01 , 1.64393255e-01 , - 1.60720782e-03 ,
70- - 7.41246708e-05 , - 6.19939758e-02 ])
71-
72- # Transformation matrix from LiDAR to vehicle frame
73- self .T_l2v = np .array ([[0.99939639 , 0.02547917 , 0.023615 , 1.1 ],
74- [- 0.02530848 , 0.99965156 , - 0.00749882 , 0.03773583 ],
75- [- 0.02379784 , 0.00689664 , 0.999693 , 1.95320223 ],
76- [0. , 0. , 0. , 1. ]])
77-
78- # Transformation matrix from LiDAR to camera frame
79- if self .camera_front :
80- self .T_l2c = np .array ([
81- [0.001090 , - 0.999489 , - 0.031941 , 0.149698 ],
82- [- 0.007664 , 0.031932 , - 0.999461 , - 0.397813 ],
83- [0.999970 , 0.001334 , - 0.007625 , - 0.691405 ],
84- [0. , 0. , 0. , 1.000000 ]
85- ])
86- else :
87- self .T_l2c = np .array ([[- 0.71836368 , - 0.69527204 , - 0.02346088 , 0.05718003 ],
88- [- 0.09720448 , 0.13371206 , - 0.98624154 , - 0.1598301 ],
89- [0.68884317 , - 0.7061996 , - 0.16363744 , - 1.04767285 ],
90- [0. , 0. , 0. , 1. ]]
91- )
92-
93- # Compute inverse transformation (camera to LiDAR)
94- self .T_c2l = np .linalg .inv (self .T_l2c )
95- self .R_c2l = self .T_c2l [:3 , :3 ]
96- self .camera_origin_in_lidar = self .T_c2l [:3 , 3 ]
97-
9888 # Initialize the YOLO detector and move to GPU if available
9989 self .detector = YOLO ('yolov8n.pt' )
10090 self .detector .to ('cuda' )
@@ -202,7 +192,7 @@ def synchronized_callback(self, image_msg, lidar_msg):
202192
203193 # Get the 3D points corresponding to the box
204194 points_3d = roi_pts [:, 2 :5 ]
205- points_3d = filter_depth_points (points_3d , max_human_depth = 0.8 )
195+ points_3d = filter_depth_points (points_3d , max_depth_diff = 0.8 )
206196 refined_cluster = refine_cluster (points_3d , np .mean (points_3d , axis = 0 ), eps = 0.15 , min_samples = 10 )
207197 refined_cluster = remove_ground_by_min_range (refined_cluster , z_range = 0.1 )
208198
@@ -275,7 +265,9 @@ def undistort_image(self, image, K, D):
275265
276266if __name__ == '__main__' :
277267 try :
278- node = YoloNode ()
268+ current_dir = os .path .dirname (__file__ )
269+ yaml_path = os .path .join (current_dir , '..' , '..' , 'knowledge' , 'calibration' , 'cameras.yaml' )
270+ node = YoloNode (yaml_path )
279271 rospy .spin ()
280272 except rospy .ROSInterruptException :
281273 pass
0 commit comments