尝试CornerNet-Lite进行目标识别并嵌入ROS

7 篇文章 0 订阅
3 篇文章 0 订阅

CornerNet-Lite是刚开源不久的实时目标检测方法,据说比YOLO3 牛逼,于是打算尝鲜一波。

首先说运行的环境要求:

1)Python 3.7

2)PyTorch 1.0.0

3)CUDA 10 (意思是你得有一张NVIDIA的显卡,比如我的是GTX1060)

4)GCC 4.9.2 or above

1. 去github下载源码

https://github.com/princeton-vl/CornerNet-Lite

git clone https://github.com/princeton-vl/CornerNet-Lite.git

2. 跟着官方readme,设置环境,这会下载一大堆东西,比如opencv, pytorch

cd <CornerNet-Lite dir>
conda create --name CornerNet_Lite --file conda_packagelist.txt --channel pytorch

这可能是一个漫长的过程(实验室这破网速,几kb的下载速度玩个XX),且在下载的pytorch的时候,可能会失败,失败,再失败,请不要气馁,奇迹总会出现,比如大清早,实验室的网速最佳,成功的几率更高哦。

3. active 你的环境

conda activate CornerNet_Lite

注意,这里是 conda ,不是source。执行完后,你会发现终端命令行前面多了(CornerNet_Lite)

这个时候你还会发现,当你在该终端下运行python时,默认是3.7版本了

4. 编译Corner Pooling Layers

cd <CornerNet-Lite dir>/core/models/py_utils/_cpools/
python setup.py install --user

5. 编译NMS

cd <CornerNet-Lite dir>/core/external
make

6. 下载模型文件

原下载地址:

CornerNet-Saccade

CornerNet-Squeeze

CornerNet

百度云走起:

链接: https://pan.baidu.com/s/1gmMpx6EUOVjfIVys_POGqQ 提取码: xtzx 复制这段内容后打开百度网盘手机App,操作更方便哦

把下载的文件放在正确的目录下:

Put the CornerNet-Saccade model under <CornerNet-Lite dir>/cache/nnet/CornerNet_Saccade/, CornerNet-Squeeze model under <CornerNet-Lite dir>/cache/nnet/CornerNet_Squeeze/ and CornerNet model under <CornerNet-Lite dir>/cache/nnet/CornerNet/

  7.  测试一下demo,看看效果如何

python demo.py

糟糕,有问题,由于本人安装了ROS,cv2.so冲突了吗?错误如下:

Traceback (most recent call last):
  File "demo.py", line 7, in <module>
    import cv2
ImportError: /opt/ros/kinetic/lib/python2.7/dist-packages/cv2.so: undefined symbol: PyCObject_Type

    检查一下python路径

Python 3.7.1 (default, Oct 23 2018, 19:19:42) 
[GCC 7.3.0] :: Anaconda, Inc. on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> sys.path
['', '/home/communicationgroup/rgbdslam2_catkin_ws/devel/lib/python2.7/dist-packages', '/opt/ros/kinetic/lib/python2.7/dist-packages', '/home/communicationgroup/anaconda3/envs/CornerNet_Lite/lib/python37.zip', '/home/communicationgroup/anaconda3/envs/CornerNet_Lite/lib/python3.7', '/home/communicationgroup/anaconda3/envs/CornerNet_Lite/lib/python3.7/lib-dynload', '/home/communicationgroup/.local/lib/python3.7/site-packages', '/home/communicationgroup/.local/lib/python3.7/site-packages/cpools-0.0.0-py3.7-linux-x86_64.egg', '/home/communicationgroup/anaconda3/envs/CornerNet_Lite/lib/python3.7/site-packages', '/home/communicationgroup/anaconda3/envs/CornerNet_Lite/lib/python3.7/site-packages/torchvision-0.2.1-py3.7.egg']

罪魁祸首正是'/opt/ros/kinetic/lib/python2.7/dist-packages'

那就删除它吧

对demo.py加入如下两行代码

#解决ros中cv2的冲突
import sys
sys.path.remove('/opt/ros/kinetic/lib/python2.7/dist-packages')

2019/4/27更新:

这样的后果是不能在.py中 import rospy,若想嵌入到ROS中,则不能采用该方法。若不用嵌入ROS,使用该方法没得问题,若要嵌入ROS中,解决办法参考后面第8节的更新。

重新运行demo.py

python demo.py

终端输出大概是这样的:

total parameters: 116969339
loading from /home/communicationgroup/CornerNet-Lite/core/../cache/nnet/CornerNet_Saccade/CornerNet_Saccade_500000.pkl
/home/communicationgroup/anaconda3/envs/CornerNet_Lite/lib/python3.7/site-packages/torch/nn/functional.py:2423: UserWarning: Default upsampling behavior when mode=bilinear is changed to align_corners=False since 0.4.0. Please specify align_corners=True if the old behavior is desired. See the documentation of nn.Upsample for details.
  "See the documentation of nn.Upsample for details.".format(mode))

结果还会在CornerNet-Lite目录下保存一张名为 demo_out.jpg 的图片

可以看出,已经把小狗仔们框出来了。

其实也并不快嘛,我的电脑(GTX1060)跑一张图像需要0.5s左右,难道是没用上GPU???2019/4/27注:平均测试速度单张图片244ms, Titan X (PASCAL) GPU

8. 尝试一下能不能用在ROS工程中

思路:相机节点通过相机获取视频,并通过ROS消息发布,图像处理节点订阅图像消息,并调用CornerNet进行目标检测。

1)C++和python参数传递

将.cpp获取的图像作为参数传给.py,实现目标识别,再将.py得到的bboxes传回给.cpp

(以后慢慢做,等更新)

2) 写一个.py节点,来订阅图像消息,并发布bboxes

由于这个CornerNet既要python3.7,又要pytorch1.0.0,还要opencv3,而ros还没有完全支持python3,所以暂时放弃该尝试。

-------------------------------------------------------------我是分割线--------------------------------------------------------------------

2019/4/27更新:

经过一番波折,实现了 .py节点的方法。测试方式:Kinect2 获取图像,test_ros.py 订阅图像消息,并调用CornerNet实现目标检测。

该方法主要是解决Python3 环境下运行ROS的问题,其中主要涉及cv_bridge,cv2的问题。网上方法形形色色,但是到我这里基本是都不得行,还害得我重装了一遍ROS。为了让大家少走弯路,这里总结一下我对Python3环境下运行ROS,并调用CornerNet的探索。

 

8.1.1 首先,解决import cv2的问题

前面第7节提到的方案在这里就不适用了,sys.path.remove('/opt/ros/kinetic/lib/python2.7/dist-packages') 会导致 import rospy失败。

cd /opt/ros/kinetic/lib/python2.7/dist-packages/
sudo mv cv2.so cv2_ros.so

意思就是重命名一下,真是简单粗暴还管用啊!

8.1.2 解决Python3 和 cv_bridge的问题

ROS默认使用python2.7,这时我们需要从源码编译cv_bridge,并在编译前设置好Python版本为Python3

1)新建ros工作空间,用于测试

mkdir py3_ws
cd py3_ws
mkdir src

2)将前面测试通过的CornerNet-Lite目录全部拷贝到 src/目录下

现在,目录结构大概是这样的 py3_ws/src/CornerNet-Lite

3)使用conda激活CornerNet-Lite环境

cd src/CornerNet-Lite/
conda activate CornerNet_Lite

跟前面一样,成功的话,终端命令行前面或多出  (CornerNet_Lite)

之所以激活该环境,是因为后续需要在该环境下调用ROS,所以得先切换到该环境下,安装rospkg等包。

 

4) 使用pip在CornerNet_Lite环境下安装rospkg、catkin_pkg等,这样才能在该环境下调用ROS

pip install catkin_pkg pyyaml empy rospkg numpy

更改CornerNet_Lite环境下opencv版本为3.4.1(CornerNet_Lite环境下的opencv版本为3.4.2,该版本在调用cv2.imshow()函数时会报错,也不知道大家的存在这个问题不)

conda install opencv==3.4.1

终端输出如下

Collecting package metadata: done
Solving environment: done

## Package Plan ##

  environment location: /home/communicationgroup/anaconda3/envs/CornerNet_Lite

  added / updated specs:
    - opencv==3.4.1


The following packages will be downloaded:

    package                    |            build
    ---------------------------|-----------------
    ffmpeg-3.4                 |       h7985aa0_0         8.0 MB
    libopencv-3.4.1            |       h8fa1ad8_3        41.5 MB
    libprotobuf-3.5.2          |       h6f1eeef_0         4.2 MB
    opencv-3.4.1               |   py37h6fd60c2_3           8 KB
    py-opencv-3.4.1            |   py37h8fa1ad8_3         1.2 MB
    ------------------------------------------------------------
                                           Total:        54.9 MB

The following NEW packages will be INSTALLED:

  libprotobuf        pkgs/main/linux-64::libprotobuf-3.5.2-h6f1eeef_0

The following packages will be DOWNGRADED:

  ffmpeg                                     4.0-hcdf2ecd_0 --> 3.4-h7985aa0_0
  libopencv                                3.4.2-hb342d67_1 --> 3.4.1-h8fa1ad8_3
  opencv                               3.4.2-py37h6fd60c2_1 --> 3.4.1-py37h6fd60c2_3
  py-opencv                            3.4.2-py37hb342d67_1 --> 3.4.1-py37h8fa1ad8_3


Proceed ([y]/n)? y


Downloading and Extracting Packages
py-opencv-3.4.1      | 1.2 MB    | ##################################################################################################################################### | 100%
opencv-3.4.1         | 8 KB      | ##################################################################################################################################### | 100%
libopencv-3.4.1      | 41.5 MB   | ##################################################################################################################################### | 100%
libprotobuf-3.5.2    | 4.2 MB    | ##################################################################################################################################### | 100%
ffmpeg-3.4           | 8.0 MB    | ##################################################################################################################################### | 100%
Preparing transaction: done
Verifying transaction: done
Executing transaction: done

安装完成后,你可以使用conda list查看该环境下都有哪些包,主要关注以下opencv、 catkin_pkg、 pyyaml、  rospkg

conda list

输出大概是这样的 (我这里多了个opencv-python 3.4.5.20,是我自己手贱安装的)

# packages in environment at /home/communicationgroup/anaconda3/envs/CornerNet_Lite:
#
# Name                    Version                   Build  Channel
blas                      1.0                         mkl  
bzip2                     1.0.6                h14c3975_5  
ca-certificates           2019.1.23                     0  
cairo                     1.14.12              h8948797_3  
catkin-pkg                0.4.12                   pypi_0    pypi
certifi                   2019.3.9                 py37_0  
cffi                      1.11.5           py37he75722e_1  
cuda100                   1.0                           0    pytorch
cycler                    0.10.0                   py37_0  
cython                    0.28.5           py37hf484d3e_0  
dbus                      1.13.2               h714fa37_1  
defusedxml                0.6.0                    pypi_0    pypi
docutils                  0.14                     pypi_0    pypi
empy                      3.3.4                    pypi_0    pypi
expat                     2.2.6                he6710b0_0  
ffmpeg                    3.4                  h7985aa0_0  
fontconfig                2.13.0               h9420a91_0  
freeglut                  3.0.0                hf484d3e_5  
freetype                  2.9.1                h8a8886c_1  
glib                      2.56.2               hd408876_0  
graphite2                 1.3.12               h23475e2_2  
gst-plugins-base          1.14.0               hbbd80ab_1  
gstreamer                 1.14.0               hb453b48_1  
harfbuzz                  1.8.8                hffaf4a1_0  
hdf5                      1.10.2               hba1933b_1  
icu                       58.2                 h9c2bf20_1  
intel-openmp              2019.0                      118  
jasper                    2.0.14               h07fcdf6_1  
jpeg                      9b                   h024ee3a_2  
kiwisolver                1.0.1            py37hf484d3e_0  
libedit                   3.1.20170329         h6b74fdf_2  
libffi                    3.2.1                hd88cf55_4  
libgcc-ng                 8.2.0                hdf63c60_1  
libgfortran-ng            7.3.0                hdf63c60_0  
libglu                    9.0.0                hf484d3e_1  
libopencv                 3.4.1                h8fa1ad8_3  
libopus                   1.2.1                hb9ed12e_0  
libpng                    1.6.35               hbc83047_0  
libprotobuf               3.5.2                h6f1eeef_0  
libstdcxx-ng              8.2.0                hdf63c60_1  
libtiff                   4.0.9                he85c1e1_2  
libuuid                   1.0.3                h1bed415_2  
libvpx                    1.7.0                h439df22_0  
libxcb                    1.13                 h1bed415_1  
libxml2                   2.9.8                h26e45fe_1  
matplotlib                3.0.2            py37h5429711_0  
mkl                       2018.0.3                      1  
mkl_fft                   1.0.6            py37h7dd41cf_0  
mkl_random                1.0.1            py37h4414c95_1  
ncurses                   6.1                  hf484d3e_0  
netifaces                 0.10.9                   pypi_0    pypi
ninja                     1.8.2            py37h6bb024c_1  
numpy                     1.15.4           py37h1d66e8a_0  
numpy-base                1.15.4           py37h81de0dd_0  
olefile                   0.46                     py37_0  
opencv                    3.4.1            py37h6fd60c2_3  
opencv-python             3.4.5.20                 pypi_0    pypi
openssl                   1.1.1b               h7b6447c_1  
pcre                      8.42                 h439df22_0  
pillow                    5.2.0            py37heded4f4_0  
pip                       19.1                     pypi_0    pypi
pixman                    0.34.0               hceecf20_3  
py-opencv                 3.4.1            py37h8fa1ad8_3  
pycparser                 2.18                     py37_1  
pyparsing                 2.2.0                    py37_1  
pyqt                      5.9.2            py37h05f1152_2  
python                    3.7.1                h0371630_3  
python-dateutil           2.7.3                    py37_0  
pytorch                   1.0.0           py3.7_cuda10.0.130_cudnn7.4.1_1  [cuda100]  pytorch
pytz                      2018.5                   py37_0  
pyyaml                    5.1                      pypi_0    pypi
qt                        5.9.7                h5867ecd_1  
readline                  7.0                  h7b6447c_5  
rospkg                    1.1.9                    pypi_0    pypi
scikit-learn              0.19.1           py37hedc7406_0  
scipy                     1.1.0            py37hfa4b5c9_1  
setuptools                40.2.0                   py37_0  
sip                       4.19.8           py37hf484d3e_0  
six                       1.11.0                   py37_1  
sqlite                    3.25.3               h7b6447c_0  
tk                        8.6.8                hbc83047_0  
torchvision               0.2.1                    py37_1    pytorch
tornado                   5.1              py37h14c3975_0  
tqdm                      4.25.0           py37h28b3542_0  
wheel                     0.31.1                   py37_0  
xz                        5.2.4                h14c3975_4  
zlib                      1.2.11               ha838bed_2  

 5)从源码编译cv_bridge

先装点依赖项吧,其实很多都有了

sudo apt-get update
sudo apt-get install python-catkin-tools python3-dev python3-catkin-pkg-modules python3-numpy python3-yaml ros-kinetic-cv-bridge

初始化工作空间,并设置Python版本为Python3(注意,这里使用的是系统默认安装的Python3.5m,测试通过,管他呢,或许Python3都可以)

cd ../../  #回到py3_ws/目录
catkin init
catkin config -DPYTHON_EXECUTABLE=/usr/bin/python3 -DPYTHON_INCLUDE_DIR=/usr/include/python3.5m -DPYTHON_LIBRARY=/usr/lib/x86_64-linux-gnu/libpython3.5m.so
catkin config --install

下载cv_bridge源码并编译

git clone https://github.com/ros-perception/vision_opencv.git src/vision_opencv

注意,这里直接下载到了src/目录下,所以不用先cd src/

 

修改src/vision_opencv/cv_bridge/CMakeLists.txt 第11行内容(解决找不到boost_python3的问题)

gedit  src/vision_opencv/cv_bridge/CMakeLists.txt

将第11行的

find_package(Boost REQUIRED python3)

修改为

find_package(Boost REQUIRED python-py35)

修改src/vision_opencv/cv_bridge/setup.py第1行内容(话说这样才会在执行的时候使用Python3???)

gedit src/vision_opencv/cv_bridge/setup.py 

将第1行的

#!/usr/bin/env python

修改为

#!/usr/bin/env python3

开始编译

catkin build cv_bridge
source install/setup.bash --extend

此处使用catkin build编译cv_bridge包,并source了一下setup.bash,让系统知道cv_bridge要用咱们这里这个。

这时可以简单测试以下能不能用

python

Python 3.7.1 (default, Oct 23 2018, 19:19:42) 
[GCC 7.3.0] :: Anaconda, Inc. on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from cv_bridge.boost.cv_bridge_boost import getCvType
>>> 

不报错或许就是莫得问题啦,那就开始写代码吧

8.1.3 来个test_ros.py脚本测试测试

cd src/CornerNet-Lite/
gedit test_ros.py 

test_ros.py内容如下

#!/usr/bin/env python3
#!coding=utf-8

import sys
import rospy

from std_msgs.msg import String
from sensor_msgs.msg import Image 
from cv_bridge import CvBridge, CvBridgeError

import cv2
print("cv2.__version__: ", cv2.__version__) 

from core.detectors import CornerNet_Saccade
from core.vis_utils import draw_bboxes

def callback(data):
    global  count, bridge, detector
    count += 1
    if count ==1:
        count = 0
        cv_img = bridge.imgmsg_to_cv2(data, "bgr8")
        bboxes = detector(cv_img)
        cv_img  = draw_bboxes(cv_img, bboxes)
        cv2.imshow("frame", cv_img)
        cv2.waitKey(3)
    else:
        pass    

def image_pro():

    # In ROS, nodes are uniquely named. If two nodes with the same
    # name are launched, the previous one is kicked off. The
    # anonymous=True flag means that rospy will choose a unique
    # name for our 'listener' node so that multiple listeners can
    # run simultaneously.
    rospy.init_node('image_pro',anonymous=True)

    global count,bridge,detector
    detector = CornerNet_Saccade()
    count = 0
    bridge = CvBridge()
    rospy.Subscriber("/kinect2/qhd/image_color_rect", Image, callback)

    # spin() simply keeps python from exiting until this node is stopped
    rospy.spin()

if __name__ == '__main__':
    image_pro()

注意:

第一行 #!/usr/bin/env python3  很重要

请修改订阅图像信息的话题名,我这儿使用的Kinect2

rospy.Subscriber("/kinect2/sd/image_color_rect", Image, callback)

8.1.4 run起来,go!go!go!

新开一个终端,运行roscore

roscore

再新开一个终端,运行相机节点(这里使用Kinect2)

rosrun kinect2_bridge kinect2_bridge

在之前那个激活了CornerNet_Lite环境的终端下运行test_ros.py

./test_ros.py 

或者

python test_ros.py 

终端输出大概是这样的

cv2.__version__:  3.4.5
total parameters: 116969339
loading from /home/communicationgroup/py3_ws/src/CornerNet-Lite/core/../cache/nnet/CornerNet_Saccade/CornerNet_Saccade_500000.pkl
/home/communicationgroup/anaconda3/envs/CornerNet_Lite/lib/python3.7/site-packages/torch/nn/functional.py:2423: UserWarning: Default upsampling behavior when mode=bilinear is changed to align_corners=False since 0.4.0. Please specify align_corners=True if the old behavior is desired. See the documentation of nn.Upsample for details.
  "See the documentation of nn.Upsample for details.".format(mode))

嘻嘻,稍等片刻,画面出现了,感谢刚哥友情出镜

效果不错啊,框出来这么多,美中不足就是有点卡。卡。卡。

 

8.1.5 出错总结:

1)如果出现如下类似错误,就是找不到'torch',应该是你没有激活环境

Traceback (most recent call last):
  File "./test_ros1.py", line 14, in <module>
    from core.detectors import CornerNet_Saccade
  File "/home/communicationgroup/py3_ws/src/CornerNet-Lite/core/detectors.py", line 1, in <module>
    from .base import Base, load_cfg, load_nnet
  File "/home/communicationgroup/py3_ws/src/CornerNet-Lite/core/base.py", line 3, in <module>
    from .nnet.py_factory import NetworkFactory
  File "/home/communicationgroup/py3_ws/src/CornerNet-Lite/core/nnet/py_factory.py", line 2, in <module>
    import torch
ImportError: No module named 'torch'

解决办法:在终端执行

conda activate CornerNet_Lite

2)如果出现如下错误,就是cv_bridge的错误,应该是你没有source 一下

[ERROR] [1556354686.771577]: bad callback: <function callback at 0x7f598b536268>
Traceback (most recent call last):
  File "/opt/ros/kinetic/lib/python2.7/dist-packages/rospy/topics.py", line 750, in _invoke_callback
    cb(msg)
  File "./test_ros1.py", line 22, in callback
    cv_img = bridge.imgmsg_to_cv2(data, "bgr8")
  File "/opt/ros/kinetic/lib/python2.7/dist-packages/cv_bridge/core.py", line 163, in imgmsg_to_cv2
    dtype, n_channels = self.encoding_to_dtype_with_channels(img_msg.encoding)
  File "/opt/ros/kinetic/lib/python2.7/dist-packages/cv_bridge/core.py", line 99, in encoding_to_dtype_with_channels
    return self.cvtype2_to_dtype_with_channels(self.encoding_to_cvtype2(encoding))
  File "/opt/ros/kinetic/lib/python2.7/dist-packages/cv_bridge/core.py", line 91, in encoding_to_cvtype2
    from cv_bridge.boost.cv_bridge_boost import getCvType
ImportError: dynamic module does not define module export function (PyInit_cv_bridge_boost)

解决办法:如果在py3_ws/src/CornerNet-Lite目录下的话,在终端执行

source ../../devel/setup.bash 

-------------------------------------------------------------我是分割线--------------------------------------------------------------------

2019/4/28更新:

8.2 既然得到了目标的框框,那就发布出来吧,以待后续工程中能够应用

8.2.1 自定义BoundingBox消息

1)首先,在py3_ws/src目录下创建cornernet_ros_msgs包,里面主要是定义了我们自己的BoundingBox消息

cd py3_ws/src/
catkin_create_pkg cornernet_ros_msgs message_generation actionlib_msgs sensor_msgs std_msgs message_runtime

创建后会发现 py3_ws/src目录下生成了一个名为cornernet_ros_msgs的文件夹,打开该文件夹,我们可以看到里面生成了CMakeLists.txtpackage.xml

2)进入cornernet_ros_msgs/目录,并创建msg文件夹,并在msg/目录下新建两个文件,分别为BoundingBox.msgBoundingBoxes.msg

cd cornernet_ros_msgs/
mkdir msg
cd msg/
gedit BoundingBox.msg 

BoundingBox.msg 中写入如下内容

string class
float64 prob
int64 x1
int64 y1
int64 x2
int64 y2

意思就是自定义了名为 BoundingBox 的消息类型,其中class为类名,prob也就是得分嘛,可以根据这个得分滤掉低于设定阈值的框框,后面的x1,y1,x2,y2就是boundingbox的坐标了。

保存一下,再创建 BoundingBoxes.msg (很多时候框框不止一个)

gedit BoundingBoxes.msg 

BoundingBoxes.msg 内容如下

Header header
BoundingBox[] bounding_boxes

意思就是里面有很多BoundingBox,存在数组(或者叫列表)中。

3)接下来就是修改修改CMakeLists.txtpackage.xml 中的内容了。

CMakeLists.txt

cmake_minimum_required(VERSION 2.8.3)
project(cornernet_ros_msgs)

## Compile as C++11, supported in ROS Kinetic and newer
add_compile_options(-std=c++11)

find_package(catkin REQUIRED COMPONENTS
  roscpp 
  rospy 
  message_generation
  actionlib_msgs
  message_runtime
  sensor_msgs
  std_msgs
)

# find_package(Boost REQUIRED COMPONENTS system)

add_message_files(
   FILES
   BoundingBox.msg
   BoundingBoxes.msg
 )

generate_messages(
   DEPENDENCIES
   actionlib_msgs
   sensor_msgs
   std_msgs
 )

catkin_package(
  CATKIN_DEPENDS 
  actionlib_msgs 
  message_runtime
  sensor_msgs 
  std_msgs
)

package.xml

<?xml version="1.0"?>
<package format="2">
  <name>cornernet_ros_msgs</name>
  <version>0.0.0</version>
  <description>The cornernet_ros_msgs package</description>
  <maintainer email="communicationgroup@todo.todo">communicationgroup</maintainer>
  <license>TODO</license>
  <buildtool_depend>catkin</buildtool_depend>
  <build_depend>message_generation</build_depend>
  <build_depend>actionlib_msgs</build_depend>
  <build_depend>sensor_msgs</build_depend>
  <build_depend>std_msgs</build_depend>
  <build_depend>message_runtime</build_depend>
  <build_export_depend>actionlib_msgs</build_export_depend>
  <build_export_depend>sensor_msgs</build_export_depend>
  <build_export_depend>std_msgs</build_export_depend>
  <exec_depend>actionlib_msgs</exec_depend>
  <exec_depend>message_runtime</exec_depend>
  <exec_depend>sensor_msgs</exec_depend>
  <exec_depend>std_msgs</exec_depend>
  <export>
  </export>
</package>

4)那就开始编译吧(就像前面编译cv_bridge一样)

cd ../../../ #回到py3_ws/目录下
catkin init

终端输出大概是这样的

Catkin workspace `/home/communicationgroup/py3_ws` is already initialized. No action taken.
--------------------------------------------------------------------------------
Profile:                     default
Extending:          [cached] /home/communicationgroup/catkin_ws/devel:/home/communicationgroup/rgbdslam2_catkin_ws/devel:/opt/ros/kinetic
Workspace:                   /home/communicationgroup/py3_ws
--------------------------------------------------------------------------------
Build Space:        [exists] /home/communicationgroup/py3_ws/build
Devel Space:        [exists] /home/communicationgroup/py3_ws/devel
Install Space:      [exists] /home/communicationgroup/py3_ws/install
Log Space:          [exists] /home/communicationgroup/py3_ws/logs
Source Space:       [exists] /home/communicationgroup/py3_ws/src
DESTDIR:            [unused] None
--------------------------------------------------------------------------------
Devel Space Layout:          linked
Install Space Layout:        merged
--------------------------------------------------------------------------------
Additional CMake Args:       -DPYTHON_EXECUTABLE=/usr/bin/python3 -DPYTHON_INCLUDE_DIR=/usr/include/python3.5m -DPYTHON_LIBRARY=/usr/lib/x86_64-linux-gnu/libpython3.5m.so
Additional Make Args:        None
Additional catkin Make Args: None
Internal Make Job Server:    True
Cache Job Environments:      False
--------------------------------------------------------------------------------
Whitelisted Packages:        None
Blacklisted Packages:        None
--------------------------------------------------------------------------------
Workspace configuration appears valid.
--------------------------------------------------------------------------------

他说我已经initialized。。。(或许不必执行catkin init???)

既然这样,那就直接编译吧

catkin build cornernet_ros_msgs

 终端输出大概是这样的

--------------------------------------------------------------------------------
Profile:                     default
Extending:          [cached] /home/communicationgroup/catkin_ws/devel:/home/communicationgroup/rgbdslam2_catkin_ws/devel:/opt/ros/kinetic
Workspace:                   /home/communicationgroup/py3_ws
--------------------------------------------------------------------------------
Build Space:        [exists] /home/communicationgroup/py3_ws/build
Devel Space:        [exists] /home/communicationgroup/py3_ws/devel
Install Space:      [exists] /home/communicationgroup/py3_ws/install
Log Space:          [exists] /home/communicationgroup/py3_ws/logs
Source Space:       [exists] /home/communicationgroup/py3_ws/src
DESTDIR:            [unused] None
--------------------------------------------------------------------------------
Devel Space Layout:          linked
Install Space Layout:        merged
--------------------------------------------------------------------------------
Additional CMake Args:       -DPYTHON_EXECUTABLE=/usr/bin/python3 -DPYTHON_INCLUDE_DIR=/usr/include/python3.5m -DPYTHON_LIBRARY=/usr/lib/x86_64-linux-gnu/libpython3.5m.so
Additional Make Args:        None
Additional catkin Make Args: None
Internal Make Job Server:    True
Cache Job Environments:      False
--------------------------------------------------------------------------------
Whitelisted Packages:        None
Blacklisted Packages:        None
--------------------------------------------------------------------------------
Workspace configuration appears valid.
--------------------------------------------------------------------------------
[build] Found '5' packages in 0.0 seconds.                                     
Starting  >>> cornernet_ros_msgs                                               
Finished  <<< cornernet_ros_msgs                [ 0.8 seconds ]                
[build] Summary: All 1 packages succeeded!                                     
[build]   Ignored:   4 packages were skipped or are blacklisted.               
[build]   Warnings:  None.                                                     
[build]   Abandoned: None.                                                     
[build]   Failed:    None.                                                     
[build] Runtime: 0.9 seconds total. 

我们最喜欢看到的就是succeed!

6) 敲代码,敲代码,把框框发布出去(只需要对前面的test_ros.py稍作修改)

暂且命名为test_ros1.py吧,内容如下,且放在py3_ws/src/CornerNet-Lite/目录下

#!/usr/bin/env python3
#!coding=utf-8

import sys
import numpy as np

import rospy

from std_msgs.msg import String
from sensor_msgs.msg import Image 
from cv_bridge import CvBridge, CvBridgeError

#自己定义的BoundingBoxes消息
from cornernet_ros_msgs.msg import BoundingBoxes
from cornernet_ros_msgs.msg import BoundingBox

import cv2
print("cv2.__version__: ", cv2.__version__) 

from core.detectors import CornerNet_Saccade
from core.vis_utils import draw_bboxes


def pub_bboxes(bboxes, thresh=0.5):
    """Public bounding boxes msgs.

    Args:
        bboxes: A dictionary representing bounding boxes of different object
            categories, where the keys are the names of the categories and the
            values are the bounding boxes. The bounding boxes of category should be
            stored in a 2D NumPy array, where each row is a bounding box (x1, y1,
            x2, y2, score).
        thresh: (Optional) Only bounding boxes with scores above the threshold
            will be drawn.

    Returns:
        None
    """  
    global pub
    bboxes_msg = BoundingBoxes()
    
    for cat_name in bboxes:
        keep_inds = bboxes[cat_name][:, -1] > thresh
             
        for bbox in bboxes[cat_name][keep_inds]:
            bbox_msg = BoundingBox( str(cat_name),             #class name
                                    bbox[-1].astype(np.float), #prab
                                    bbox[0].astype(np.int32),  #x1
                                    bbox[1].astype(np.int32),  #y1
                                    bbox[2].astype(np.int32),  #x2
                                    bbox[3].astype(np.int32))  #y2
                                                 
            bboxes_msg.bounding_boxes.append(bbox_msg) 
    # print(bboxes_msg)
    pub.publish(bboxes_msg) 



def callback(data):
    global  count, bridge, detector
    count += 1
    if count ==1:
        count = 0
        cv_img = bridge.imgmsg_to_cv2(data, "bgr8")
        bboxes = detector(cv_img)
        cv_img  = draw_bboxes(cv_img, bboxes)
        cv2.imshow("frame", cv_img)
        pub_bboxes(bboxes) #发布消息
        cv2.waitKey(3)
    else:
        pass    

def image_pro():

    # In ROS, nodes are uniquely named. If two nodes with the same
    # name are launched, the previous one is kicked off. The
    # anonymous=True flag means that rospy will choose a unique
    # name for our 'listener' node so that multiple listeners can
    # run simultaneously.
    rospy.init_node('image_pro',anonymous=True)
    
    global count,bridge,detector,pub
    detector = CornerNet_Saccade()
    count = 0
    bridge = CvBridge()
    rospy.Subscriber("/kinect2/qhd/image_color_rect", Image, callback)
    pub = rospy.Publisher('boundingboxes',BoundingBoxes,queue_size=10)
    # spin() simply keeps python from exiting until this node is stopped
    rospy.spin()

if __name__ == '__main__':
    image_pro()

7)试一试,看看消息能发布出来不(看看程序能跑不)

先激活CornerNet_Lite环境,并source一下工作空间

cd py3_ws/src/CornerNet-Lite
conda activate CornerNet_Lite
source ../../devel/setup.bash 

运行test_ros1.py(假设你已经启动了roscore 和相机节点,参考8.1.4节)

./test_ros1.py 

 东西框出来了,那消息发布出去了么?那就rostopic list看一看

新开一个终端

rostopic list 

这是终端会输出ROS发布的所有消息,我的大概是这样的,很棒,第一个就是我们需要的

communicationgroup@Z370:~/py3_ws/src/CornerNet-Lite$ rostopic list 
/boundingboxes
/kinect2/cap/camera_info
/kinect2/cap/cap_bgr
/kinect2/cap/cap_bgr/compressed
/kinect2/cap/cap_mono
/kinect2/cap/cap_mono/compressed
/kinect2/hd/camera_info
/kinect2/hd/image_color
/kinect2/hd/image_color/compressed
/kinect2/hd/image_color_rect
/kinect2/hd/image_color_rect/compressed
/kinect2/hd/image_depth_rect
/kinect2/hd/image_depth_rect/compressed
/kinect2/hd/image_mono
/kinect2/hd/image_mono/compressed
/kinect2/hd/image_mono_rect
/kinect2/hd/image_mono_rect/compressed
/kinect2/qhd/camera_info
/kinect2/qhd/image_color
/kinect2/qhd/image_color/compressed
/kinect2/qhd/image_color_rect
/kinect2/qhd/image_color_rect/compressed
/kinect2/qhd/image_depth_rect
/kinect2/qhd/image_depth_rect/compressed
/kinect2/qhd/image_mono
/kinect2/qhd/image_mono/compressed
/kinect2/qhd/image_mono_rect
/kinect2/qhd/image_mono_rect/compressed
/kinect2/sd/camera_info
/kinect2/sd/image_color_rect
/kinect2/sd/image_color_rect/compressed
/kinect2/sd/image_depth
/kinect2/sd/image_depth/compressed
/kinect2/sd/image_depth_rect
/kinect2/sd/image_depth_rect/compressed
/kinect2/sd/image_ir
/kinect2/sd/image_ir/compressed
/kinect2/sd/image_ir_rect
/kinect2/sd/image_ir_rect/compressed
/rosout
/rosout_agg

再用rostopic echo /boundingboxes 看看里面具体是些啥

communicationgroup@Z370:~/py3_ws/src/CornerNet-Lite$ rostopic echo /boundingboxes 
ERROR: Cannot load message class for [cornernet_ros_msgs/BoundingBoxes]. Are your messages built?

哎呀,看到ERROR就尴尬了!其实这都是小问题啦,因为新开这个终端没有source工作空间,他怎么理解我们自己定义的消息呢,那就source一下

source ~/py3_ws/devel/setup.bash 

然后再echo

rostopic echo /boundingboxes 

终端输出大概是这样的

communicationgroup@Z370:~/py3_ws/src/CornerNet-Lite$ rostopic echo /boundingboxes 
header: 
  seq: 1
  stamp: 
    secs: 0
    nsecs:         0
  frame_id: ''
bounding_boxes: 
  - 
    class_: "bottle"
    prob: 0.650504469872
    x1: 1
    y1: 300
    x2: 43
    y2: 444
  - 
    class_: "bottle"
    prob: 0.597384572029
    x1: 123
    y1: 310
    x2: 154
    y2: 381
  - 
    class_: "cup"
    prob: 0.739920139313
    x1: 94
    y1: 379
    x2: 182
    y2: 472
  - 
    class_: "chair"
    prob: 0.736968696117
    x1: 719
    y1: 368
    x2: 917
    y2: 536
  - 
    class_: "tv"
    prob: 0.689738988876
    x1: 283
    y1: 246
    x2: 428
    y2: 350
  - 
    class_: "mouse"
    prob: 0.543673157692
    x1: 381
    y1: 388
    x2: 423
    y2: 408
  - 
    class_: "keyboard"
    prob: 0.587634801865
    x1: 228
    y1: 386
    x2: 369
    y2: 427
  - 
    class_: "book"
    prob: 0.500504910946
    x1: 501
    y1: 291
    x2: 590
    y2: 306
---

没错,这就是我们想要的。以后具体应用的时候,还是该把Header加上,这样就可以根据时间戳等信息知道这些框框对应哪一帧图像的。

最后备注:

代码中detector=CornerNet_Saccade(),是否可以改一改呀?不是有三个models嘛,这个就留给大家去探索吧(悄悄告诉大家,CornerNet_Squeeze很快哦

那就这样吧,本篇博客正式完结。

参考链接:

https://github.com/princeton-vl/CornerNet-Lite

https://stackoverflow.com/questions/49221565/unable-to-use-cv-bridge-with-ros-kinetic-and-python3?rq=1

https://community.bwbot.org/topic/499/%E5%9C%A8ros%E4%B8%AD%E4%BD%BF%E7%94%A8python3

 

 

 

 

 

 

 

  • 8
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 11
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值