1前景提要:
-
cv_bridge是ros中常用的訊息型別轉換的包(ros自帶的包),要在ros環境下利用opencv處理USB相機拍攝的視頻必須用到cv_bridge(如下圖),詳見https://blog.csdn.net/Robogreen/article/details/50487382

-
在網上找到相應文章之后(詳見https://blog.csdn.net/qq_28306361/article/details/85142192,代碼也貼在下面了),將代碼copy過來,catkin_make的時候發現有以下錯誤提示:

#include <ros/ros.h>
#include <stdio.h>
#include <image_transport/image_transport.h>
#include <cv_bridge/cv_bridge.h>
#include <sensor_msgs/image_encodings.h>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
static const char WINDOW[] = "Image window";
static void help()
{
printf("\nThis program demonstrates converting OpenCV Image to ROS Image messages \n"
);
}
int main(int argc, char** argv)
{
help();
ros::init(argc, argv, "image_converter");
//Reading an image from the file
cv::Mat cv_image = cv::imread("/home/vlt/Pictures/1.jpg");
if(cv_image.empty() )
{
ROS_ERROR("Read the picture failed!");
return -1;
}
//Convert OpenCV image to ROS message
ros::NodeHandle node;
image_transport::ImageTransport transport(node);
image_transport::Publisher image_pub;
image_pub=transport.advertise("OutImage", 1);
ros::Time time=ros::Time::now();
cv_bridge::CvImage cvi;
cvi.header.stamp = time;
cvi.header.frame_id = "image";
cvi.encoding = "bgr8";
cvi.image = cv_image;
sensor_msgs::Image im;
cvi.toImageMsg(im);
image_pub.publish(im);
ROS_INFO("Converted Successfully!");
//Show the image
cv::namedWindow(WINDOW);
cv::imshow(WINDOW,cv_image);
cv::waitKey(0);
ros::spin();
return 0;
}
主要是那兩個未定義的參考讓人頭大,因為代碼中還有其他cv::imread等opencv庫中的函式,為什么唯獨錯誤提示中的那兩個函式顯示未定義的參考呢?
2解決程序(這個程序可以略去不看,直接看下面的最終解決辦法)
- 卸載系統自帶的opencv2,重新下載安裝并配置opencv2.4.9(見https://blog.csdn.net/weixin_40522162/article/details/79921370)
- 還是一樣的報錯,然后又在程式的cmakelist中添加了庫的鏈接(見https://blog.csdn.net/qq_37340588/article/details/107057987):
set(OpenCV_DIR /usr/local/opencv2.4.9/share/OpenCV)
find_package(OpenCV 2.4.9 REQUIRED)
include_directories(SYSTEM ${OpenCV_INCLUDE_DIRS} /usr/local/opencv2.4.9/include)
link_directories(${OpenCV_LIBRARY_DIRS} /usr/local/opencv2.4.9/lib))
- 還是一樣的報錯,這個時候人都傻了啊啊啊啊啊啊啊啊,甚至想卸載重裝ros了,明明位置已經指定的明明白白的了,為什么還是未定義呢???
- 然后看到了一篇博客(見https://blog.csdn.net/bigdog_1027/article/details/79092263),終于明白了,原來先前的很多參考博客都沒有提到cv_bridge,只是解決了opencv的版本問題,而我用的程式出錯的罪魁禍首是cv_bridge這個包,詳見3最終解決辦法,
3最終解決辦法
- 首先我們要明白,如果最開始安裝的是完整的ros的話,是會自帶opencv包的,ros-kinetic自帶的是opencv3.3.1-dev,我們在/opt/ros/kinetic/include/opencv-3.3.1-dev這個路徑下可以看到它,

- 但是,ros自帶的opencv包是很不完整的,有很多函式都沒有,比如我們進入opencv2/highgui查看highgui.hpp頭檔案(如下圖),可以看到里面甚至沒有內容

- 最重要的是,cv_bridge的cmake檔案(里面寫了這個包需要鏈接的一些庫)中默認呼叫的是ros自帶的opencv3.3.1-dev,而且經過之前報錯的實踐可以知道cv_bridge呼叫opencv版本優先級是高于我們寫的CmakeList檔案呼叫的opencv的,也就是說,只要我們用了cv_bridge,無論在CmakeList中指定的opencv庫路徑是哪里,它都會默認呼叫ros自帶的opencv3.3.1-dev,而通過上面兩點我們知道,ros自帶opencv庫是不完整的,所以會出現某些函式報“未定義的參考”的錯,
- 那么怎么解決這個問題呢?最佳辦法就是修改cv_bridge的cmake檔案,讓它默認呼叫我們指定的opencv庫,修改如下:
1.首先在終端中輸入cd /opt/ros/kinetic/share/cv_bridge/cmake
2.然后輸入sudo gedit cv_bridgeConfig.cmake
3.然后修改以下兩處(圖片借鑒于博客https://blog.csdn.net/bigdog_1027/article/details/79092263):

opencv庫檔案(均為動態庫so檔案)有很多,在這里我們只是添加了最常用的幾種,如果之后有需要還可以再在這個檔案中添加,
5.最后保存檔案,在CmakeList中添加cv_bridge依賴包,就可以用我們指定的opencv版本啦,
參考鏈接
1.cv_bridge的原理講解:https://blog.csdn.net/Robogreen/article/details/50487382
2.cv_bridge的簡單應用:https://blog.csdn.net/qq_28306361/article/details/85142192
3.opencv的安裝和配置:https://blog.csdn.net/weixin_40522162/article/details/79921370
4.Cmakelist添加opencv庫地址:https://blog.csdn.net/qq_37340588/article/details/107057987
5.cv_bridge默認的opencv3和CmakeList中指定的opencv2沖突的問題:https://blog.csdn.net/bigdog_1027/article/details/79092263
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/294806.html
標籤:其他
