In the project, we often need to compile multiple OpenCV libraries due to the version dependency of OpenCV. But when we use ROS, it will default to the cross-compilation folder /usr/lib/aarch64-linux-gnu/ (mine is an arm architecture, so the middle is aarch64-linux-gnu, and the x86 machine is /usr/lib /x86-64-linux-gnu/) folder to generate the opencv library, taking the melodic version as an example, the automatically generated library version is 3.2.0, and the noetic version is 4.2.0.
At this time, if the OpenCV version required by one of my devices is 3.3, it may conflict with it and cause a conflict error or warn. And because the corresponding version of CV_bridge is specified as the OpenCV library under this path ( /usr/lib/aarch64-linux-gnu/ ), serious problems will be caused at this time, and errors such as this will appear:
libopencv_imgcodecs.so.3.2, needed by /opt/ros/melodic/lib/libcv_bridge.so, may conflict with libope
and some undefined references. The above is an error caused by cv_bridge.
We know that when multiple versions of OpenCV are installed on the device, we need to specify the path of your OpenCV in the cmakelists
set(OpenCV_DIR xxxxxxxxx)
Then complete the version selection through find and other operations, or through
find(OpenCV xx REQUIRED)
xx is the specified version, if this can solve the problem, it is done.
But there are also errors reported in the cross-compilation part. We clearly selected a fixed version of OpenCV but still reported an error. In the link, we still saw the library linked to the cross-compiled folder. At this time, we checked cmakelists.txt and found that when generating dynamic libraries, there are only two linked libraries: $(catkin_LIBRARIES) and ${OpenCV_LIBRARIES}
So where is the problem? Because the error is generated in OpenCV, is it a problem with OpenCV? In fact, it is not? Let's check the contents of the two variables by printing them out:
message(STATUS " include path: ${OpenCV_INCLUDE_DIRS}")
message(STATUS " LIBRARIES: ${OpenCV_LIBRARIES}")
message(STATUS " catkin_LIBRARIES: ${catkin_LIBRARIES}")
can be seen:
This part of the OpenCV3.2 library is brought by the content of $(catkin_LIBRARIES) , then we can remove this part of the opencv library .
At this point use:
file(GLOB_RECURSE OLD_OPENCV "/usr/lib/aarch64-linux-gnu/libopencv*")
list(REMOVE_ITEM catkin_LIBRARIES ${OLD_OPENCV})
This is the operation of two cmakelists, a brief introduction: reference link
Adding the above two sentences before the link library will exclude the opencv library that comes with ros. We can verify it by outputting:
Found it was gone. If there are only such problems, the direct compilation can pass.
If the error report contains the cv_bridge problem mentioned at the beginning of the article, you need to modify cv_bridge:
In the /opt/ros/melodic/share/cv_bridge/cmake path sudo use gedit or vim to open cv_bridgeConfig.cmake
After opening it, we found that cv_bridge points to the OpenCV version that comes with ROS because of the version coordination. At this time, we only need to modify the following two places (the picture below is the revised version):
#原1:
if(NOT "include;/usr/include;/usr/include/opencv4 " STREQUAL " ")
#根据你所需的OpenCV路经改为:
if(NOT "include;/usr/include;/usr/local/include/opencv" STREQUAL " ")
#原2:
set(libraries "cv_bridge;/usr/lib/aarch64-linux-gnu/libopencv_core.so.3.2.0;/usr/lib/aarch64-linux-gnu/libopencv_imgproc.so.3.2.0;/usr/lib/aarch64-linux-gnu/libopencv_imgcodecs.so.3.2.0")
#根据你所需的OpenCV库的路经改为:
set(libraries "cv_bridge;/usr/local/lib/libopencv_core.so.3.3.1;/usr/local/lib/libopencv_imgproc.so.3.3.1;/usr/local/lib/libopencv_imgcodecs.so.3.3.1")
Compile again to pass.
------------------------------------------------------------------------------------------------------------------------
Summarize:
1. When using multiple versions of OpenCV, first specify the version to see if it can solve the problem;
2. When there is no cv_bridge error, it prompts a conflict, check the content of $(catkin_LIBRARIES) , and exclude the OpenCV library that comes with ROS;
3. When there is an error of cv_bridge, it will prompt a conflict, and modify the cv_bridgeConfig.cmake file of /opt/ros/melodic/share/cv_bridge/cmake .
postscript: