安装Ubuntu 18.04自带的opencv:
sudo apt install libopencv*
安装的是Opencv 3.2.0.8版本。
注意,该版本的opencv_python会有些问题,在使用cv.namedWindow()函数时会说找不到该函数。所以转而使用opencv-3.4.7版本
当自带的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的动态库的原因,转而使用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的python代码在运行时会出现找不到rospkg模块的问题,可通过如下方法解决:
$ conda install setuptools
$ pip install -U rosdep rosinstall_generator wstool rosinstall six vcstools
其实在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相关的代码,前提是需要将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秒钟。如此便不会再出现第二次无法启动的问题。
这个例子综合了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来运行)。如果脚本正常可以得到如下图的显示结果。