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

背景:html

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

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管理的問題。算法

解決方案:ubuntu

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

1. CMake下指定Opencv版本post

關鍵文件: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中添加ui

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

個人OpenCVConfig.cmake在spa

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

注意,將其添加在project(MyProjectName)以前。3d

如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
相關文章
相關標籤/搜索