基于ROS的LiDAR数据如何直接接入TensorFlow/Keras神经网络
ROS Kinetic Python2.7 订阅/scan话题对接Keras方案
- 核心思路是通过rospy订阅
/scan话题,在回调函数中直接提取LiDAR的测距数组,转为numpy数组后即可直接输入到已加载的Keras模型中推理,无需中转csv文件。
完整可运行代码示例
#!/usr/bin/env python # -*- coding: utf-8 -*- import rospy import numpy as np from sensor_msgs.msg import LaserScan from keras.models import load_model from keras.models import Sequential from keras.layers import Dense # 全局变量存储模型和推理结果 model = None inf_result = 0 def lidar_callback(scan_data): global model, inf_result # 提取LiDAR 360个测距点,和你之前csv取的0:360维度对应 lidar_arr = np.array(scan_data.ranges[:360]) # 处理测距的无效值(超出范围/探测不到的点会是inf/nan),这里替换成你传感器的最大测距值即可 lidar_arr[np.isnan(lidar_arr)] = 10.0 lidar_arr[np.isinf(lidar_arr)] = 10.0 # 增加batch维度,适配Keras输入要求 model_input = np.expand_dims(lidar_arr, axis=0) # 直接推理,这里输出的就是你原来y对应的预测结果 inf_result = model.predict(model_input)[0][0] # 可以根据需求打印或者发布推理结果 rospy.loginfo("当前推理结果:%.4f"%inf_result) if __name__ == "__main__": # 初始化ROS节点 rospy.init_node("lidar_keras_infer", anonymous=False) # 加载你训练好的模型,如果你是刚训练完也可以直接在这里写模型结构加载权重 # 下面是你原来的模型结构示例,注意input_dim要和你输入的LiDAR维度对齐,你原来写的input_dim=8和取的360维不一致,这里要改 model = Sequential() model.add(Dense(12, input_dim=360, activation='relu')) model.add(Dense(8, activation='relu')) model.add(Dense(1, activation='sigmoid')) # 加载训练好的权重,你训练完可以用model.save_weights("lidar_model.h5")保存,这里直接加载就行 # model.load_weights("lidar_model.h5") # 订阅/scan话题,队列大小设为1避免旧数据积压 rospy.Subscriber("/scan", LaserScan, lidar_callback, queue_size=1) rospy.spin()
注意事项
- 运行前需要给Python文件加可执行权限:
chmod +x lidar_keras_infer.py - 你的模型输入维度要和LiDAR提取的维度保持一致,你示例代码中原本写的
input_dim=8和csv取的360维存在矛盾,需要根据你的实际数据维度修改 - Python2.7 适配的TensorFlow最高版本为1.15,Keras最高版本为2.2.4,版本不匹配会出现接口报错
- 如果不需要每帧都推理,可以在回调函数中增加帧计数逻辑,每隔N帧推理一次,降低CPU/GPU占用
内容的提问来源于stack exchange,提问作者Anto
相关产品推荐
相关产品推荐

