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)
Related
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?
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.
So I am trying to work with the Kinect by using the libfreenect driver and OpenCV. I want to be able to create the project using CMake. I was able to get the proper CMakeList for me to be able to load the OpenCV librery. Now I want to input video using the kinect but cant find any help for this.
Also I'm using Ubuntu 12.04 64bit on a laptop.
How can I do this using Cmake?
p.s. I was able to install libfreenect properly, the demo programs run just fine.
You might want to have a look at this:
cmake_minimum_required(VERSION 2.8 FATAL_ERROR)
project("My Project")
find_package(OpenCV REQUIRED)
find_package(Threads REQUIRED)
find_package(libfreenect REQUIRED)
include_directories("/usr/include/libusb-1.0/")
add_executable(regtest src/regtest.cpp
src/features.cpp)
target_link_libraries(regtest ${OpenCV_LIBS}
${CMAKE_THREAD_LIBS_INIT}
${FREENECT_LIBRARIES})
add_executable(main src/main.cpp
src/features.cpp)
target_link_libraries(main ${OpenCV_LIBS}
${CMAKE_THREAD_LIBS_INIT}
${FREENECT_LIBRARIES})
This is the CMakeLists.txt I used for a project using both OpenCV and freenect.
i am using opencv with another library. So i would like to compile a class if OpenCV has CUDA.
i need to acheive this in Cmake file. But i cannot find any variable that tells whether OpenCV
has CUDA or not.
FindOpenCV.cmake defines these variables
OpenCV_FOUND
OpenCV_LIBS
OpenCV_INCLUDE_DIR
OpenCV_VERSION
now how can i find out if OpenCV is compiled with CUDA or not from this cmake file?
Here is the list of CMake variables, that can help you:
OpenCV_COMPUTE_CAPABILITIES - compute capability from which OpenCV has been compiled, can be added to nvcc flags.
list(APPEND CUDA_NVCC_FLAGS ${OpenCV_COMPUTE_CAPABILITIES})
OpenCV_CUDA_VERSION - CUDA toolkit version which was used to build OpenCV, if OpenCV was built without CUDA support, the variable is empty. You can check this variable:
if(OpenCV_CUDA_VERSION)
# Have CUDA support
endif()
OpenCV_USE_CUBLAS - true if OpenCV was built with CUBLAS support
OpenCV_USE_CUFFT - true if OpenCV was built with CUFFT support
OpenCV_USE_NVCUVID - true if OpenCV was built with NVCUVID support
I would like to run surfgpu on ubuntu .But do not know how to write cmakelists.I have installed the CUDA 4.2 SDK and Toolkit, and C inside the program can run.My development environment is Qt.ubuntu 11.10.opencv2.4.2 any good suggestions are appreciated.
How about this?
# CMakeLists.txt to build OpenCV project
cmake_minimum_required(VERSION 2.8)
project( testOpenCV )
Find OpenCV and CUDA package
find_package(OpenCV REQUIRED )
find_package(CUDA 4.2 REQUIRED)
Include from some directories
# Since surf is a non free package, you also have to add non free include dir
include_directories( ${OpenCV_INCLUDE_DIR} "${OpenCV_SOURCE_DIR}/modules/nonfree/include" ${CUDA_INCLUDE_DIRS})
Compile source
cuda_add_executable( exefile source.cpp source2.cpp )
target_link_libraries( exefile ${OpenCV_LIBS} ${otherlibsyouneed} )
All of the above only work if you compiled OpenCV with -DHAVE_CUDA