开发软件


eclipse CDT,用于C/C++语言下开发ROS和opencv程序
Pycharm Commnunity,用于Python语言下开发ROS和opencv程序
Anaconda2-2019.07,Python语言环境。之所以按照Python2.7对应版本,是因为ROS1.0的Python接口是2.7的。
OpenCV的简易安装与配置
安装Ubuntu 18.04自带的opencv:

sudo apt install libopencv*

安装的是Opencv 3.2.0.8版本。
注意,该版本的opencv_python会有些问题,在使用cv.namedWindow()函数时会说找不到该函数。所以转而使用opencv-3.4.7版本

OpenCV的编译与配置


当自带的opencv有问题或者无法满足要求时,需要自行编译和配置opencv。

首先下载opencv源代码,我们使用3.4.7版本。同时下载ippicv_2019_lnx_intel64_general_20180723.tgz文件

解压opencv 3.4.7,将ippicv_2019_lnx_intel64_general_20180723.tgz放入到/opencv-3.4.7/3rdparty/ippicv目录下。

在终端下执行cmake-gui命令。设置好source code目录和build目录,然后分别点击Configure按钮。然后注意检查是否有BUILD_opencv_python2项存在,是否勾选了。如果没有则通过"Add Entry"按钮手动添加一个,并使其勾选。然后再点击Generate按钮。其它一般使用默认的设置即可。

Eigen3的小修改


ubuntu下安装的libeigen3-dev在进行编译opencv时会提示找不到头文件,可通过如下方式解决:

sudo ln -s /usr/include/eigen3/Eigen /usr/include/Eigen
sudo ln -s /usr/include/eigen3/unsupported /usr/include/unsupported

在终端下执行:

cd /opt/nfs/opencv-3.4.7/build
make -j8
# 等待编译完成后
sudo make install

配置路径。在/etc/ld.so.conf.d/目录下建立opencv.conf文件,内容为"/usr/local/lib",然后在~/.bashrc文件最好加上如下内容:

PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/usr/local/lib/pkgconfig

进行这样的配置后就可以使用C++进行opencv相关的开发。不知道为什么编译不出opencv for python的动态库

opencv for python配置
由于编译的OpenCV不能产生For python的动态库的原因,转而使用pip来安装。
首先配置pip的国内源,建立~/.config/pip/pip.conf文件,内容如下:

PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/usr/local/lib/pkgconfig

进行这样的配置后就可以使用C++进行opencv相关的开发。不知道为什么编译不出opencv for python的动态库

opencv for python配置
由于编译的OpenCV不能产生For python的动态库的原因,转而使用pip来安装。
首先配置pip的国内源,建立~/.config/pip/pip.conf文件,内容如下:
————————————————

[global]
index-url = https://pypi.tuna.tsinghua.edu.cn/simple

然后使用pip安装:

pip install opencv-python==3.4.7.28
pip install opencv-contrib-python==3.4.7.28

Anaconda和ROS的兼容问题

在保持Anaconda环境的情况下,ROS的python代码在运行时会出现找不到rospkg模块的问题,可通过如下方法解决:

$ conda install setuptools
$ pip install -U rosdep rosinstall_generator wstool rosinstall six vcstools

创建简单的ROS包

其实在ROS下的package是并不区分C++和python的,一个package下即可以有python文件也可以有c++文件。

cd ~/xxx/ros_ws/src
catkin_create_pkg python_test std_msgs rospy
mkdir python_test/scripts

在scripts子目录下创建test_publisher.py。内容如下

#!/usr/bin/env python
import rospy
from std_msgs.msg import String

def talker():
	pub = rospy.Publisher('hello_pub', String, queue_size=10)
	rospy.init_node('hello_world_publisher', anonymous=True)
	r=rospy.Rate(10)
	while not rospy.is_shutdown():
		str="hello world %s"%rospy.get_time()
		rospy.loginfo(str)
		pub.publish(str)
		r.sleep()

if __name__ == '__main__':
	try:
		talker()
	except rospy.ROSInterruptException: pass

再创建test_subscriber.py,内容如下:

#!/usr/bin/env python

import rospy
from std_msgs.msg import String

def callback(data):
	rospy.loginfo(rospy.get_caller_id()+"I heard %s", data.data)

def listener():
	rospy.init_node('hello_world_subscriber', anonymous=True)
	rospy.Subscriber("hello_pub", String, callback)
	rospy.spin()

if __name__ == '__main__':
	listner()

再进行Build和执行

cd ~/xxx/ros_ws/
catkin_make
source devel/setup.bash
rosrun python_test test_publisher.py
rosrun python_test test_subscriber.py

使用pycharm运行ROS代码
要在pycharm中运行ROS相关的代码,前提是需要将ROS的环境进行source。所有在终端中执行pycharm时是可以正常运行ros的python代码的,因为以及在~/.bashrc中配置ROS的环境,但是如果是在GUI界面下运行pycharm,则无法正常运行ROS的python代码,会提示找不到rospy库等错误。下面提出解决的方法。首先在桌面建立pycharm的快捷方式:

gedit ~/Desktop/pycharm.desktop
##内容为
[Desktop Entry]
Name=pyCharm
Exec=bash -i -c "/opt/pycharm-community-2019.2.2/bin/pycharm.sh" %f
Icon=/opt/pycharm-community-2019.2.2/bin/pycharm.png
Terminal=false
Type=Application
Name[en_US]=pyCharm

这样处理之后,再点击桌面上的pyCharm图标即可运行配置了ROS环境的pyCharm IDE。可以试着运行一下
注意 在自己的笔记本(ubuntu 18.04)上会出现问题,第一次可以启动,但关闭pycharm后第二次启动不了,bash会一直占用CPU导致死机。将Terminal改为true之后就可以再次启动。分析了一下原因,可能是关闭pycharm时,bash过早退出会产生问题,所以将Exec改为:

Exec=bash -i -c "/opt/pycharm-community-2019.2.2/bin/pycharm.sh; sleep 3" %f

让pycharm关闭时,bash再保持3秒钟。如此便不会再出现第二次无法启动的问题。

通过OpneCV处理ROS输出的摄像头图像
这个例子综合了ROS和OpenCV的应用。
首先创建一个package:

catkin_create_pkg vision_py rospy std_msgs sensor_msgs cv_bridge

也可以利用现有的package,只需要再package得CMakeLists.txt中的find_package中加入sensor_msgs和cv_bridge依赖包即可。
在visio_py/scripts目录中建立camera_disp.py脚本文件,内容如下:

#!/usr/bin/env python
# -*- coding: UTF-8 -*-

import rospy
import sys
import cv2
from sensor_msgs.msg import Image
from cv_bridge import CvBridge, CvBridgeError

class cvBridgeDemo():
    def __init__(self):
        self.node_name = "cv_bridge_demo"
        rospy.init_node(self.node_name)
        rospy.on_shutdown(self.cleanup)     #当ros关闭时对opencv进行清理
        self.bridge = CvBridge()
        #订阅usb_cam发布的图像topic, 当得到数据类型为Image的图像时调用对于回调函数image_callback
        self.image_sub = rospy.Subscriber("/usb_cam/image_raw", Image, self.image_callback) 
	#每30ms执行一次show_img_cb,用于刷新显示窗口中的图像
        rospy.Timer(rospy.Duration(0.03), self.show_img_cb) 
    def show_img_cb(self, evnet):
        try:
            cv2.namedWindow("Camera Image", cv2.WINDOW_NORMAL);
            cv2.imshow("Camera Image", self.frame)
            cv2.waitKey(3)
        except:
            pass
    def image_callback(self,ros_image):
        try:
            self.frame = self.bridge.imgmsg_to_cv2(ros_image, "bgr8")
        except CvBridgeError, e:
            print e
    def cleanup(self):
        cv2.destroyAllWindows()

def main(args):
    try:
        cvBridgeDemo()
        rospy.spin()
    except KeyboardInterrupt:
        cv2.destroyAllWindows()
if __name__ == '__main__':
    main(sys.argv)

然后对该package进行catkin_make。接下来就可以进行测试了
首先运行摄像头节点:

roslaunch usb_cam usb_cam-test.launch

然后在pycharm中运行刚才的camera_disp.py脚本(或者通过rosrun来运行)。如果脚本正常可以得到如下图的显示结果。