前言:在看相关博客时,说ros Indigo中使用的是opencv2,然后用
pkg-config --modversion opencv命令查了一下自己的opencv版本是3.2.0(下载完整版的ros自带),那不得下载一个opencv2编译c++程序嘛?于是乎想着整个opencv多版本共存使用,来回折腾,后来才意识到,我的ros不是melodic版本嘛,Indigo下的cv_bridge需要用opencv2编译不代表melodic呀!不过来回的折腾倒是打通了一些编译知识上的任督二脉。
1.有关OpenCV的知识
OpenCV是一个计算机视觉处理库,里面包含丰富的且已经封装好的视觉处理程序,用户只需要调用其API接口,就可以使用相关功能,避免了研究者们重复造轮子。
OpenCV支持C++、python等编程开发语言,python适合入门,C++编译效率更高。
2.ros和opencv的关系
3.在系统中已有opencv的情况下,下载opencv的其他版本,实现多版本共存
下载opencv2时,camke中使用的代码如下:
cmake -D CMAKE_BUILD_TYPE=RELEASE -D CMAKE_INSTALL_PREFIX=/usr/local/opencv_2 -D WITH_CUDA=OFF -D WITH_OPENGL=OFF -D WITH_OPENCL=OFF -D BUILD_JPEG=OFF -D BUILD_PNG=OFF -D BUILD_JASPER=OFF -DBUILD_OPENEXR=OFF -D BUILD_TIFF=OFF -D BUILD_ZLIB=OFF -D WITH_FFMPEG=OFF -D ENABLE_PRECOMPILED_HEADERS=OFF ..
单独建立一个文件夹:将编译的文件放置在/usr/local/opencv_2文件夹下,这是多版本共存的关键。系统自带的opencv是分布在/usr/include、/usr/share、/usr/lib、/usr/bin下的,防止覆盖。
4.Cmakelists.txt的编写
首先,按照上述参考确认opencv在Ubuntu环境下可以正常运行,这说明OpenCV安装成功,然后为了能够在ros下使用opencv,关键在于Cmakelist.txt的编写,只有这个写正确了,在ros工作空间下编译才能正常进行,才能找到相应的可执行文件。
这里,主要是修改Cmakelist,由于是Opencv多版本共存,在Cmakelists中对opencv头文件(include)和库文件(lib)的路径指定尤为重要,指定不正确,编译的时候就会报错,说是“相应的函数未定义”等等问题。在网上查了一圈,那些常规的解决方法,都不太管用。
根据这篇博客,我camkelist文件编写(下面是调用自己下载的opencv2进行编译)如下:
cmake_minimum_required(VERSION 3.0.2)
project(fire)
find_package(catkin REQUIRED COMPONENTS
cv_bridge
image_transport
roscpp
rospy
sensor_msgs
std_msgs
)
set(OpenCV_INCLUDE_DIRS /usr/local/opencv_2/include;/usr/local/opencv_2/include/opencv)
set(OpenCV_LIBRARIES opencv_highgui;opencv_imgproc;opencv_superres;opencv_videostab;opencv_video;opencv_viz;opencv_ml;opencv_objdetect;opencv_shape;opencv_stitching;opencv_photo;opencv_imgcodecs;opencv_videoio;opencv_calib3d;opencv_flann;opencv_features2d;opencv_core)
#set(OpenCV_DIR /usr/share/OpenCV)
#find_package(OpenCV REQUIRED)
#include_directories(${OpenCV_INCLUDE_DIRS})
include_directories(
# include
${catkin_INCLUDE_DIRS}
)
add_executable(fire src/fire.cpp)
target_link_libraries(fire ${catkin_LIBRARIES})
target_link_libraries(fire ${OpenCV_LIBRARIES})
add_executable(pub_string src/pub_string.cpp)
target_link_libraries(pub_string ${catkin_LIBRARIES})
程序正确编译并运行。
上述代码中还有一部分注释是切换使用ros自带的opencv,也是查找常规方法未能解决,有一篇博客提到ros answers中有一个解决方法,依葫芦画瓢之后成功编译。
注意:cmakelist中的代码编写顺序,如果代码正确,顺序不对,可能会出现rosrun找不到可执行文件等问题。
5.编译相关的问题
众所周知,c++程序是要通过cmakelist进行编译生成相应的可执行文件,而python程序可直接作为可执行文件使用,如果是在ros中使用python编程,那么就不需要写cmakelist,那系统如何辨别将python文件链接到opencv2还是系统自带的opencv版本呢?这就需要在.bashrc下声明相关的环境变量,然后查询opencv的版本,python会链接到相应的opencv版本。