背景:

最近,在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

Ubuntu下多个版本OpenCV管理(Multiple Opencv version)的更多相关文章

  1. ubuntu下升级R版本

    ubuntu下升级R版本   在测试<机器学习 实用案例解析>一书的邮件分类代码时,windows系统下rstudio中无法读取特殊字符,在ubuntu下可以.在ubuntu虚拟机下安装t ...

  2. Ubuntu下查看软件版本及安装位置【转】

    Ubuntu下查看软件版本及安装位置 查看软件版本:     aptitude show xxx 也可用apt-show-versions (要先安装sudo apt-get install apt- ...

  3. 更改Ubuntu下默认Python版本

    更改Ubuntu下默认Python版本 首先查看系统内有哪些版本的Python ls /usr/bin/python* 查看当前python版本 python --version 基于用户修改默认版本 ...

  4. ubuntu下安装多版本Python

    今天一不小心又把ubuntu系统给完坏了,因为我把python3卸载了,然后就...好了,不废话了,接下来就说一下如何在ubuntu下管理python的多个版本.我这里使用的是一个叫pyenv的Pyt ...

  5. Ubuntu下的MongoDB GUI 可视化管理工具

    目录 1 Robo 3T 2 NoSQLBooster for MongoDB(收费) 3 JetBrains Plugin Repository :: Mongo Plugin Ubuntu下的Mo ...

  6. linux/ubuntu下最简单好用的python opencv安装教程 ( 解决 imshow, SIFT, SURF, CSRT使用问题)

    希望这篇文章能彻底帮你解决python opencv安装和使用中的常见问题. 懒人请直奔这一节, 一条命令安装 opencv 使用python-opencv常用的问题 在linux中使用python版 ...

  7. Ubuntu下更改Python版本

    https://www.jianshu.com/p/9d3033d1b26f 有些命令运行失败,是因为权限不够,前面加上 sudo 首先查看Python默认版本: ubuntu@user~$:pyth ...

  8. Android实战技巧之八:Ubuntu下切换JDK版本【转】

    本文转载自:http://blog.csdn.net/lincyang/article/details/42024565 Android L之后推荐使用JDK7编译程序,这是自然发展规律,就像是4年前 ...

  9. Ubuntu下查看linux版本,内核版本,系统位数,gcc版本

    1. 查看linux版本  sunny@ubuntu:~$cat /etc/issueUbuntu 11.04 \n \l 2. 查看内核版本1) sunny@ubuntu:~$ cat /proc/ ...

随机推荐

  1. sklearn安装

    1.准备工作 安装sklearn之前,我们需要先安装numpy,scipy函数库. 由于用pip install numpy, scipy大概率安装失败(Win下),一个简单的解决方法是安装UCI第三 ...

  2. unity3d的碰撞检测及trigger

    A.基本概念 要产生碰撞必须为游戏对象添加刚体(Rigidbody)和碰撞器,刚体可以让物体在物理影响下运动.碰撞体是物理组件的一类,它要与刚体一起添加到游戏对象上才能触发碰撞.如果两个刚体相互撞在一 ...

  3. 深度强化学习——连续动作控制DDPG、NAF

    一.存在的问题 DQN是一个面向离散控制的算法,即输出的动作是离散的.对应到Atari 游戏中,只需要几个离散的键盘或手柄按键进行控制. 然而在实际中,控制问题则是连续的,高维的,比如一个具有6个关节 ...

  4. python中的模块及包及软件目录结构规范

    知识内容: 1.模块的定义与分类 2.模块的导入 3.模块与包 4.不同目录下的模块调用 一.模块的定义与分类 1.什么是模块 模块就是实现了某个功能的代码集合,模块是由一大堆代码构成的 类似于函数式 ...

  5. 不规则ROI的提取

    在网上看到基于opencv3.0之前的API实现不规则ROI的提取,我自己试了一下发现opencv3.0不行,第一想法是我写的有问题,最后发现是API的改版.原理很简单. 目标:提取黑线作为ROI 原 ...

  6. PHP图片压缩

    <?php /** * 分享请保持网址.尊重别人劳动成果.谢谢. * 图片压缩类:通过缩放来压缩.如果要保持源图比例,把参数$percent保持为1即可. * 即使原比例压缩,也可大幅度缩小.数 ...

  7. 今天练手了下mysqlbinlog,标记下

    1 首先查看是否开启了 bin log 登录mysql后  使用命令 show variables like "log_%"; show binary logs; 2  确认开启了 ...

  8. Genymotion——VirtualBox cannot start virtual device

    提示"VirtualBox cannot start virtual device" 打开VirtualBox,想要在里面直接启动Genymotion模拟器,又出现错误,提示“Un ...

  9. 使用seaborn制图(小提琴图)

    import numpy as np import pandas as pd import matplotlib.pyplot as plt import seaborn as sns # 设置风格, ...

  10. mavenLocal默认地址转移

    maven的默认本地仓库为 USER_HOME/.m2/ windows开发我们大多不会讲本地仓库放在c盘下,而是重新指定了另一个存储位置. 在gradle中 使用 mavenLocal() 时的查找 ...