Linking ROS Noetic to opencv build from source - opencv

I am writing a ROS node which uses OpenCV and SIFT (ROS Noetic, Ubuntu 20.04).
As of OpenCV version 4, the SIFT algorithm is part of the opencv_contrib package.
Within my ROS node, I want to use the ROS package cv_bridge, to convert between the OpenCV image format and ROS image sensor messages.
My understanding is that
Code in the opencv_contrib package is only usable if such package is built together with OpenCV from source.
cv_bridge depends on the Ubuntu package version of OpenCV, libopencv-dev.
I currently have both installed (the Ubuntu package and the version compiled from source) and I am trying to have my node depend on the source-compiled one, in order to use the non-free algorithms.
My procedure in order to do this is (after compiling OpenCV with the additional modules and OPENCV_ENABLE_NONFREE=ON) adding to the CMakeLists.txt of my package the following lines:
find_package(OpenCV PATHS .../opencv-4.5.4/cmake)
include_directories(include ${catkin_INCLUDE_DIRS} .../opencv-4.5.4/include)
link_directories(.../opencv-4.5.4/lib)
add_executable(...)
target_link_libraries(nodeName ${catkin_LIBRARIES} .../opencv-4.5.4/lib)
in order to link my code to the compiled version of OpenCV. However, when I try to build it with catkin build I obtain:
In file included from [...]:
[...]/markerDetection.h:8:10: fatal error: opencv2/xfeatures2d.hpp: No such file or directory
8 | #include <opencv2/xfeatures2d.hpp>
I suspect that ROS is trying to link to the version I installed through the package manager, which in fact does not have the opencv2/xfeatures2d.hpp library.
Am I setting the wrong options in CMakeLists.txt? Is what I am trying to do even possible?

Related

Why cv_bridge uses OpenCV 3.2 in ROS Melodic?

I have OpenCV 3.4 installed in Ubuntu 18. I also have installed ROS Melodic according to the website instructions. However, I keep on getting an error that libopencv_core.so.3.2 is required.
I already set my CMakeLists files to point to OpenCV 3.4.
However, I found out that in the file:
/ros/melodic/share/cv_bridge/cmake/cv_bridgeConfig.cmake
there is the following line hardcoded in opencv3.2:
set(libraries "cv_bridge;/usr/lib/x86_64-linux-gnu/libopencv_core.so.3.2.0;/usr/lib/x86_64-linux-gnu/libopencv_imgproc.so.3.2.0;/usr/lib/x86_64-linux-gnu/libopencv_imgcodecs.so.3.2.0").
I tried to change it to 3.4 but I can not rebuild it.
The error I am getting is:
/opt/ros/melodic/lib/image_view/image_view: error while loading shared libraries: libopencv_core.so.3.2: cannot open shared object file: No such file or directory
Why is OpenCV 3.2 hardcoded in cv_bridge and how can I rebuild it with OpenCV 3.4?
Update:
I eventually installed OpenCV 3.2 and it worked properly.
Because opencv development speed is much faster than ROS individual module. And a lot of ROS modules went depreciated after someone left the job.
But that's by no means the end of the day( maybe end of the day for noobs). You can build it directly with any version of opencv core function(besides imshow kind of function) others should perform just fine.
The easiest way is to do is: in the console before executing catkin_make try to execute the following
export CMAKE_PREFIX_PATH=/usr/local:$CMAKE_PREFIX_PATH
export LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH
This should give preference to your custom OpenCV installation when doing the find_package(OpenCV 3.X.0 REQUIRED). Then compile and use the function of that version.
Well if you do have to use 3.4 then I think you have to build ros version of opencv and image transport and cvbridge to the 3.4 if that's what you are targeting.
You can find the link here https://github.com/ros-gbp/opencv3-release The highest they provide seems to be 3.3

How to build openCV 3.3.0 with GStreamer on Windows

Having Gstreamer 1.22 successfully installed I'm not able to configure the project to build OpenCV. CMake isn't able to find GStreamer on my machine. Any ideas how two address this issue?
Just found the solution:
Cmake is using FindGstreamerWindows.cmake to find GStreamer on Windows, which is using internal an environment variable called "GSTREAMER_DIR" pointing to ..\gstreamer\1.0\x86_64.
Please make sure GSTREAMER_DIR exists on your machine.
I recently compile Opencv 4.2 with GStreamer on Windows. I use settings for GStreamer as on the following pictures. Make sure you point to correct .lib and include directories. all_Library is gstapp-1.0.lib etc, when configuraing CMAKE to compile OpenCV.
I use Opencv 4.2, CMake 3.17.0 release candidate and Gstreamer 1.16.2 MSVC 64-bit (VS 2019) developer and runtime installer. The whole process is described here install OpenCV on windows GStreamer tutorial
The important part is to set up environmental variables to find Gstreamer Runtime. Into system variable path: add
xxx\1.0\x86_64\bin
xxx\1.0\x86_64\lib
xxx\1.0\x86_64\lib\gstreamer-1.0
Gstreamer pipe from c++ opencv program to the web.

OpenCV error: No GPU support, cannot build with WITH_CUDA=ON

I am trying to make OpenCV project using GPU. I installed OpenCV v2.4.13 and NVidia CUDA Toolkit. I added additional include and library directories in configuration and OpenCV project works correctly without GPU functions. But when I'm trying to run openCV with GPU I get an error like this:
OpenCV Error: No GPU support (The library is compiled without CUDA support) in EmptyFuncTable::mallocPitch, file C:\builds\2_4_PackSlave_win32_vc12-shared\opencv\modules\dynamicuda\include\opencv2/dynamicuda/dynamicuda.hpp, line 126
Libary has been compiled without CUDA, so i tried to build the sources myself, with WITH_CUDA=ON in CMake, but when building Visual Studio 2013 has been giving me an errors that he cannot find opencv_core2413d.lib.
What can I do with this?

opencv3 linking from ROS kinetic

all!
I am trying to use OpenCV library in CLion project, but this is unsuccessful. I have opencv 3.2.0 installed with ROS kinetic at once (I can see it in /opt/ros/kinetic/include/opencv-3.2.0 directory and I can import cv2 by python). But when I use such CMakeLists.txt:
cmake_minimum_required(VERSION 3.6)
project(visual_slam)
set(CMAKE_CXX_STANDARD 11)
set(SOURCE_FILES main.cpp)
set(OpenCV_DIR /opt/ros/kinetic/include/opencv-3.2.0)
include_directories( ${OpenCV_DIR})
add_executable(visual_slam ${SOURCE_FILES})
with the next simple code:
#include <iostream>
#include <opencv2/opencv.hpp>
using namespace cv;
int main()
{
return 0;
}
I get the next error:
CMakeFiles/visual_slam.dir/main.cpp.o: In function cv::String::~String()':
/opt/ros/kinetic/include/opencv-3.2.0/opencv2/core/cvstd.hpp:664: undefined reference tocv::String::deallocate()'
CMakeFiles/visual_slam.dir/main.cpp.o: In function cv::String::operator=(cv::String const&)':
/opt/ros/kinetic/include/opencv-3.2.0/opencv2/core/cvstd.hpp:672: undefined reference tocv::String::deallocate()'
Such error was discussed also in OpenCV linking problems with ROS, but is it really so necessary to uninstall completely and then install again OpenCV? Is there any more quick solution?
Second question, how to correctly add OpenCV from ROS to CMakeLists.txt? Current CMakeLists (look above) does not look like to be flexible. I've already tried to add
find_package(OpenCV 3 REQUIRED)
target_link_libraries(visual_slam ${OpenCV_LIBRARIES} )
but the error is when CMake builds
By not providing "FindOpenCV.cmake" in CMAKE_MODULE_PATH this project has asked CMake to find a package configuration file provided by "OpenCV", but
CMake did not find one.
Could not find a package configuration file provided
by "OpenCV" (requested version 3) with any of the following names:
OpenCVConfig.cmake
opencv-config.cmake
The second error you are getting (namely the missing OpenCV.cmake) is actually not only related to the first one (the undefined reference to) but is the cause.
If cmake fails to find the OpenCV module the ${OpenCV_LIBS} won't do a thing meaning that target_link_libraries(visual_slam ${OpenCV_LIBRARIES} ) doesn't link against the libraries your code requires. That said I also believe that it's OpenCV_LIBS instead of OpenCV_LIBRARIES.
You can of course specify the path where the find_package(...) command looks at to find cmake modules (I think it was the CMAKE_FIND_ROOT_PATH variable) or even manually specify the root folder of your OpenCV installation and manually handle all the things that the OpenCV.cmake handles for you.
Last but not least I'm not sure if ROS Kinetic uses the latest OpenCV (what you are using namely the v3.2). You should check that and if different versions are used (very likely), you will have to build all ROS OpenCV-related packages from scratch. You might ask "Why should I do that?". Well, to avoid compatibility issues and various weird errors that may or may not occur (depending on what OpenCV functionality you use) due to version X of OpenCV being used for the binary packages of ROS and version Y present on your system (with X != Y). I had to do that with PCL (Point Cloud Library) once and it took me several days to come to this conclusion since the errors that I was getting were (typical for C++) cryptic as hell. To avoid conflicts make sure that only the one version of OpenCV is present on your system (that is can be found by cmake) that you want to use with your ROS installation. That's also the reason why the ROS binary packages are shipped through the Ubuntu repos using dependencies that are resolved by the package manager (OpenCV, PCL etc.).
PS: Since I haven't used Clion I would also suggest (before doing anything I've mentioned above) to check if it's not some hidden cmake-related setting inside the IDE that screws things up.

Forcing cmake to use a specific OpenCV version

My Ubuntu 14.04 has OpenCV 2.4.8 installed by default, and I also have a hand-built OpenCV 2.4.11 that I need for the cv::fisheye classes, which I build with cmake to produce my executable. The problem is that I am using ROS, which also defaults to 2.4.8, but I need to link with 2.4.11. The hack I have in place is:
find_package(OpenCV REQUIRED)
# Needed to force OpenCV 2.4 to link with 2.4.11
#message("Initial value for ${OpenCV_VERSION}: ${OpenCV_LIBS}")
if(OpenCV_VERSION VERSION_LESS "3.0")
set(OpenCV_VERSIONED_LIBS "")
macro(set_opencv_version version)
foreach( LIB_FILE ${ARGN} )
set(OpenCV_VERSIONED_LIBS ${OpenCV_VERSIONED_LIBS} :lib${LIB_FILE}.so.${version})
endforeach()
endmacro()
set_opencv_version("2.4.11" ${OpenCV_LIBS})
else()
set(OpenCV_VERSIONED_LIBS ${OpenCV_LIBS})
endif()
#message("Updated value: ${OpenCV_VERSIONED_LIBS}")
target_link_libraries(my_fisheye_application
${OpenCV_VERSIONED_LIBS}
${catkin_LIBRARIES}
cv_bridge # This by default pulls in OpenCV 2.4.8 libraries
# ...etc...
)
As this script needs to work on different machines and with OpenCV 3.0 as well as 2.4.11, I cannot really make any assumptions about the directories in use. Is there a better way to do this?
If you want to force CMake (the FindOpenCV module) to search for an OpenCV library different from the package/system installed one,
you need to set OpenCV_ROOT_DIR variable to the base directory of OpenCV tree to use.
Also, because you want at least a specific minimum version of the OpenCV library, it's better to state it in the find_package() function, as the following:
find_package(OpenCV 2.4.11 REQUIRED)

Resources