本文主要讲述在ROS下使用opencv进行图像处理,并给出了一个详细示例。
首先建立一个ros包,在CMakeLists.txt中加入以下代码段,用于找到并链接OpenCV。安装完整版的ROS会顺带把OpenCV 2.4.x也装了,不过可能不太完整,缺一些头文件或者库之类的。最好自己再装一遍,直接去OpenCV官网或者github下载源码编译安装,也可对Ubuntu系统下安装依赖性有进一步了解。如系统中存在多个opencv版本的情况,可参考《ubuntu 安装使用多版本opencv》这篇博客。
find_package(OpenCV REQUIRED)
include_directories(${OpenCV_INCLUDE_DIRS})
target_link_libraries(${PROJECT_NAME} ${OpenCV_LIBS})
在ROS中通过cv_bridge包实现ros图像和opencv图像的转换,通过image_transport包订阅和发布图像数据。
此外,ros indigo版本的cv_bridge依赖于opencv2.4.x。如果自己装的版本过高,可能会存在兼容性问题,导致图像或视频无法加载。其解决办法可参考博文《OpenCV 3与ROS兼容、OpenCV多版本共存》,主要是下载cv_bridge后重新编译。
ROS和OpenCV的关系图如下,图片来源于ros官网。
下面介绍一个简单的图像处理示例,实现对黑色条纹的检测(有点类似于智能车比赛的摄像头组)。由于黑色像素较为明显,因此先对图像进行灰度处理变成单通道的,再进行Ostu阈值分割(大津法),得到二值化的图像就只有0和1了,其中为0的部分为黑色。
关键代码段如下:
cv::Mat image = cv::imread(argv[1], CV_LOAD_IMAGE_COLOR);
cv::Mat gray;
cv::Mat edges;
cv::cvtColor(image, gray, cv::COLOR_BGR2GRAY);
cv::threshold(gray, edges, 76, 255, CV_THRESH_OTSU); //参数76可设置成自动调节
我写了两个节点,一个用于加载图像并进行图像,一个用于显示图像,两个要同时运行才可看到效果。运行时别忘了source工作空间,并打开roscore。
rosrun img_process read_img_node argv[1]
rosrun img_process show_img_node
运行中的效果截图如下:
以上是针对静态图像的处理,如果视频流和从摄像头获取的,图像处理的过程还是一样,只是获取的地方改成如下:
cv::VideoCapture cap(argv[1]); //传入摄像头参数或视频文件目录
if(!cap.isOpened())
return;
cv::Mat frame;
cap >> frame; //这样便可实时获取图像数据
此外,笔者还提供了matlab程序进行同样的处理,效果如下(貌似在ros下效果好点):
不过总的来说,这只是一个简单的示例,实际运用中还有很多没有考虑的地方,如光照、噪点等。
整个工程的源代码在下面的网址可以下到:
https://github.com/WelinLee/ROS_OPENCV_PRO