Autoware vision-dpm-ttic-detect结果的可视化
首先我们启动vison-dpm-ttic-detect,可以在topic中看到下面这样的输出.为了调试,我们需要把检测的结果可视化出来。即用框框将检测到的object在图像中框出来。我们打算用python写一个package去完成这项任务。
环境的准备
像这篇《用Python实现ROS节点》介绍一样,首先我们要创建一个ros的package。
- 首先,我们cd到src目录下,此处我的目录是:
~/m_ros_node/src
- 然后创建package:
catkin_create_pkg m_vision
我以创建test为例,执行上述命令后的结果是
3. cd到src上层目录,编译并且source。最后建立py文件存放目录src
cd ..
catkin_make
source devel/setup.bash
cd src/test/
mkdir include
mkdir src
以test为例,见下图
4. 因为我们需要接收vison-dpm-ttic-detect的识别结果,而其发布到通道的数据格式是autoware自定义的结构ImageObj,所以我们需要在python中也实现相关的结构,很幸运,autoware已经为我们实现了ImageObj的python版。存放在
Autoware/ros/devel/lib/python2.7/dist-packages/autoware_msgs
中。为了方便使用pycharm时的代码提示,我们将
Autoware/ros/devel/lib/python2.7/dist-packages/
下的所有文件拷贝到python环境中。
这里有个小细节:在ros中,对于msg有一个标识_md5sum,用于判断两种数据结构是否相同。可以看到下面ImageObj的python和C++版有着相同的标识。相同的标识表示相同的数据结构,这在ros-Subscriber接收通道数据时会判断通道中的数据是否是符合代码给定的数据类型,如果是则会触发回调函数,否则不触发回调函数。
ImageObj的python版
class ImageObj(genpy.Message):
# 数据结构的标识
_md5sum = "07ef08924af0932bcdf48f6ca49c8c23"
_type = "autoware_msgs/ImageObj"
_has_header = True #flag to mark the presence of a Header object
_full_text = """Header header
ImageObj的C++版
template<class ContainerAllocator>
struct MD5Sum< ::autoware_msgs::ImageObj_<ContainerAllocator> >
{
#数据结构的标识
static const char* value()
{
return "07ef08924af0932bcdf48f6ca49c8c23";
}
static const char* value(const ::autoware_msgs::ImageObj_<ContainerAllocator>&) { return value(); }
static const uint64_t static_value1 = 0x07ef08924af0932bULL;
static const uint64_t static_value2 = 0xcdf48f6ca49c8c23ULL;
};
代码实现部分
看源码即可。
#!/usr/bin/env python
from sensor_msgs.msg import Image
import cv2
from autoware_msgs.msg import ImageObj
import rospy
from cv_bridge import CvBridge
class ObjShow:
def __init__(self, img_path, obj_person_path=None, obj_car_path=None):
self.ros_img_path = img_path
if obj_person_path is not None:
self.ros_obj_person_path = obj_person_path
else:
print('obj-person is None')
self.ros_obj_person_path = None
if obj_car_path is not None:
self.ros_obj_car_path = obj_car_path
else:
print('obj-car is None')
self.ros_obj_car_path = obj_car_path
self.img = None
self.obj_car = None
self.obj_person = None
self.bridge = CvBridge()
def callback_img(self, image):
"""
image_raw callback function
:param image: image data
:return:
"""
self.img = self.bridge.imgmsg_to_cv2(image, desired_encoding="bgr8")
def callback_person(self, obj_person):
"""
image ojb callback function
:param obj_person:
:return:
"""
for obj in obj_person.obj:
if obj.score > 0.3:
cv2.rectangle(self.img, (obj.x, obj.y), (obj.x + obj.width, obj.y + obj.height), (0, 255, 0), 2)
# print('x: ', obj.x)
# print('y: ', obj.y)
# print('height: ', obj.height)
# print('width: ', obj.width)
# print('--------------')
self.obj_person = obj_person
cv2.imshow('person', self.img)
cv2.waitKey(1)
def run(self):
rospy.init_node('m_obj_show', anonymous=True)
rospy.Subscriber(self.ros_img_path, Image, self.callback_img)
if self.ros_obj_person_path is not None:
rospy.Subscriber(self.ros_obj_person_path, ImageObj, self.callback_person)
# spin() simply keeps python from exiting until this node is stopped
rospy.spin()
if __name__ == '__main__':
obj_show = ObjShow(img_path='/image_raw', obj_person_path='/obj_person/image_obj')
obj_show.run()
启动
修改该python文件为可执行文件
sudo chmod +x obj_show.py
启动
- 播放图像数据
使用实现录制好的bag文件
- 启动autoware的vision-dpm-ttic-detect
- 启动编写好的模块
rosrun m_vision obj_show.py
- autoware自带的model效果并不好,而且此处我们没有对时间戳做处理,所以打上的框框有延迟。