Ubuntu下多個版本OpenCV管理(Multiple Opencv version)


背景:

最近,在Nvidia的GPU嵌入式開發板Jetson TX1(簡稱TX1)上移植深度學習目標檢測算法YOLO。在TX1上安裝了官方提供的opencv版本——OpenCV4Tegra(OpenCV-2.4.12),但是使用該版本opencv VideoCapture在讀取攝像頭數據時出錯,顯示錯誤:

Unable to stop the stream.: Device or resource busy Unable to stop the stream.: Bad file descriptor

使用Google試圖找到解決方法,最后發現官方給出答案,只能重新安裝Opencv3.0以上的 版本。我使用Nvidia論壇jkjung提供的方法安裝OpenCV3.1.0。安裝完成后,我使用的TX1 Ubuntu14.04上安裝了兩個版本的OpenCV, Opencv-2.4.12和Opencv-3.1.0。因此,我面臨着如何在程序中指定使用期望版本的OpenCV,即Ubuntu下多個版本Opencv管理的問題。

解決方案:

現在討論Ubuntu14.04下分別使用CMake和Makefile編譯運行帶Opencv程序的兩種解決方案。

1. CMake下指定Opencv版本

關鍵文件:OpenCVConfig.cmake。在opencv編譯好后,所在目錄中一般會有一個叫OpenCVConfig.cmake的文件,這個文件中指定了CMake要去哪里找OpenCV,其.h文件在哪里等,比如其中一行:

# Provide the include directories to the caller
set(OpenCV_INCLUDE_DIRS "/home/ubuntu/src/opencv-3.1.0/build" "/home/ubuntu/src/opencv-3.1.0/include" "/home/ubuntu/src/opencv-3.1.0/include/opencv")

只要讓CMake找到這個文件,這個文件就指定了Opencv的所有路徑,因此設置OpenCV_DIR為包含OpenCVConfig.cmake的目錄,如在我的C++工程CMakeLists.txt中添加

set(OpenCV_DIR "/home/ubuntu/src/opencv-3.1.0/build")

我的OpenCVConfig.cmake在

/home/ubuntu/src/opencv-3.1.0/build

注意,將其添加在project(MyProjectName)之前。

如CMakeLists.txt內容如下:

cmake_minimum_required(VERSION 2.8)
set(OpenCV_DIR "/home/ubuntu/src/opencv-3.1.0/build")
project( camera )
find_package( OpenCV REQUIRED )
add_executable( camera camera.cpp )
target_link_libraries( camera ${OpenCV_LIBS} )

因此,我們期望使用哪個版本的Opencv,只要找到對應的OpenCVConfig.cmake文件,並且將其路徑添加到工程的CMakeLists.txt中即可了。

2. Makefile下指定Opencv版本

關鍵文件:opencv.pc 。在Makefile下,應該是可以在其中詳細設定Opencv路徑,要使用到哪些庫等等(我沒有仔細學習過Makefile的使用)。在此,我想介紹一種簡單的在Makefile下指定期望使用的Opencv版本的方法,該方法借助linux下pkg-config命令。

我們常常使用pkg-config --modversion 來查看指定庫的版本,比如查看opencv版本pkg-config --modversion opencv。其實pkg-config顯示的信息來自於這個庫對應的.pc文件,比如安裝了opencv后,我們可以在/usr/lib/pkg-config/ 文件夾下找到opencv.pc,內容如下:

# Package Information for pkg-config

prefix=/usr
exec_prefix=${prefix}
libdir=${exec_prefix}/lib
includedir_old=${prefix}/include/opencv
includedir_new=${prefix}/include

Name: OpenCV
Description: Open Source Computer Vision Library
Version: 2.4.12.2
Libs: -L${exec_prefix}/lib -lopencv_calib3d -lopencv_contrib -lopencv_core -lopencv_features2d -lopencv_flann -lopencv_gpu -lopencv_highgui -lopencv_imgproc -lopencv_legacy -lopencv_ml -lopencv_objdetect -lopencv_photo -lopencv_stitching -lopencv_superres -lopencv_ts -lopencv_video -lopencv_videostab -lopencv_detection_based_tracker -lopencv_esm_panorama -lopencv_facedetect -lopencv_imuvstab -lopencv_tegra -lopencv_vstab -L/usr/local/cuda-7.0/targets/armv7-linux-gnueabihf/lib -lcufft -lnpps -lnppi -lnppc -lcudart -ltbb -lrt -lpthread -lm -ldl
Cflags: -I${includedir_old} -I${includedir_new}

當然,我們也可以使用

pkg-config --cflags opencv
pkg-config --libs opencv

分別查看opencv庫的包含目錄(include/, .h)和庫名稱(.so)。在Makefile中,可以通過以上命令設定opencv庫相關目錄。如下:

COMMON+= -DOPENCV
CFLAGS+= -DOPENCV
LDFLAGS+= `pkg-config --libs opencv`
COMMON+= `pkg-config --cflags opencv`

此時Makefile對應的工程使用的opencv庫即為opencv.pc文件中所指的版本。本例中為2.4.12.2。

那么可以容易想到,如果我在/usr/lib/pkgconfig文件夾目錄下添加opencv-3.1.0.pc文件,是否就可以將版本指向opencv-3.1.0l了呢?答案是肯定的。

我在編譯opencv-3.1.0的編譯目錄下/home/ubuntu/src/opencv-3.1.0/build/目錄下找到了unix-install/opencv.pc文件,其內容如下:

# Package Information for pkg-config

prefix=/home/ubuntu/opencv-3.1.0
exec_prefix=${prefix}
libdir=${exec_prefix}/lib
includedir_old=${prefix}/include/opencv
includedir_new=${prefix}/include

Name: OpenCV
Description: Open Source Computer Vision Library
Version: 3.1.0
Libs: -L${exec_prefix}/lib -lopencv_cudabgsegm -lopencv_cudaobjdetect -lopencv_cudastereo -lopencv_shape -lopencv_stitching -lopencv_cudafeatures2d -lopencv_superres -lopencv_cudacodec -lopencv_videostab -lopencv_cudaoptflow -lopencv_cudalegacy -lopencv_calib3d -lopencv_features2d -lopencv_objdetect -lopencv_highgui -lopencv_videoio -lopencv_photo -lopencv_imgcodecs -lopencv_cudawarping -lopencv_cudaimgproc -lopencv_cudafilters -lopencv_video -lopencv_ml -lopencv_imgproc -lopencv_flann -lopencv_cudaarithm -lopencv_core -lopencv_cudev

我發現其中的路徑是不太准確的,更正為:

# Package Information for pkg-config

prefix=/home/ubuntu/src/opencv-3.1.0
exec_prefix=${prefix}/build
libdir=${exec_prefix}/lib
includedir_old=${prefix}/include/opencv
includedir_new=${prefix}/include

Name: OpenCV
Description: Open Source Computer Vision Library
Version: 3.1.0
Libs: -L${exec_prefix}/lib -lopencv_cudabgsegm -lopencv_cudaobjdetect -lopencv_cudastereo -lopencv_shape -lopencv_stitching -lopencv_cudafeatures2d -lopencv_superres -lopencv_cudacodec -lopencv_videostab -lopencv_cudaoptflow -lopencv_cudalegacy -lopencv_calib3d -lopencv_features2d -lopencv_objdetect -lopencv_highgui -lopencv_videoio -lopencv_photo -lopencv_imgcodecs -lopencv_cudawarping -lopencv_cudaimgproc -lopencv_cudafilters -lopencv_video -lopencv_ml -lopencv_imgproc -lopencv_flann -lopencv_cudaarithm -lopencv_core -lopencv_cudev

並將其拷貝到/usr/lib/pkgconfig目錄下,並重命名為opencv-3.1.0.pc,將原來的opencv.pc重命名為opencv-2.4.12.pc。

那么當我期望使用opencv-3.1.0時,Makefile中為:

COMMON+= -DOPENCV
CFLAGS+= -DOPENCV
LDFLAGS+= `pkg-config --libs opencv-3.1.0`
COMMON+= `pkg-config --cflags opencv-3.1.0`

當我期望使用opencv-2.4.12時,Makefile中為:

COMMON+= -DOPENCV
CFLAGS+= -DOPENCV
LDFLAGS+= `pkg-config --libs opencv-2.4.12`
COMMON+= `pkg-config --cflags opencv-2.4.12`

從而實現了多個版本OpenCV的使用。

備注:

運行make之后,運行可執行程序時,可能會提示找不到庫的錯誤(not find libopencv-core.so.3.1之類),那時因為動態庫目錄不在程序搜索庫目錄的路徑下,系統默認的動態庫搜索路徑有/usr/local/lib等,OpenCV4Tegra(opencv-2.4.12)生成的庫都在/usr/local/lib目錄,但opencv-3.1.0的庫在/home/ubuntu/src/opencv-3.1.0/build/lib中,不在搜索路徑中,因此,只需要添加其為搜索路徑即可。添加方法為/etc/ld.so.conf.d/libc.conf中添加/home/ubuntu/src/opencv-3.1.0/build/lib。libc.conf文件內容如下:

# libc default configuration
/usr/local/lib
/home/ubuntu/src/opencv-3.1.0/build/lib

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM