自动包含不同版本的 OpenCV 库

Posted

技术标签:

【中文标题】自动包含不同版本的 OpenCV 库【英文标题】:Automatically Including OpenCV Libraries of Different Versions 【发布时间】:2012-04-05 21:18:02 【问题描述】:

我已经在 Windows 7 上的 Visual Studio 2008 上自动包含我的 c++ 代码的 opencv 库文件,代码如下:

#ifndef NDEBUG
#pragma comment(lib, "opencv_core231d.lib")
#pragma comment(lib, "opencv_highgui231d.lib")
#pragma comment(lib, "opencv_imgproc231d.lib")
#else
#pragma comment(lib, "opencv_core231.lib")
#pragma comment(lib, "opencv_highgui231.lib")
#pragma comment(lib, "opencv_imgproc231.lib")
#endif 

但是当系统安装了不同版本的 opencv 库时我遇到了麻烦,因为 .lib 文件的文件名中有版本(在本例中为 2.31)。有没有一种好方法可以自动或接近自动检测可用的 opencv 库版本,然后将适当的版本字符串滑入 pragma 中?

【问题讨论】:

我正在审查这个老问题,想知道连接方案?见:gcc.gnu.org/onlinedocs/cpp/Concatenation.html 【参考方案1】:

不同的 OpenCV 版本之间存在细微的变化 - 变化不大,但足以在您从 2.0 更改为 2.2 或从 2.2 更改为 2.3.1 时使您的应用崩溃。此外,beta 2.4 版本与以前的版本相比有足够的变化。

所以最好是使用 OpenCV 版本测试您的应用,并仅使用这些 dll 交付它。

一个小例子:

Mat a(3,3,CV_8UC3);

a.setTo( Scalar(10) ); // in 2.3.1 will set all channels to 10,
// in 2.2 will only set first channel. 

相应的 2.2 调用将是

a.setTo(Scalar::all(10));

或者

a = 0; // runs fine on 2.3.1. Equivalent to setTo().
// Does not compile on earlier versions

另一个例子是cv::drawPoly(),它在 2.2 和 2.3.1 上有不同的签名。

鉴于这些更改没有得到很好的记录,因此错误地错过其中一个的机会非常高。

【讨论】:

这是一条有效的评论并已注明。但是,1)理论上可以通过分支同时支持多个版本,2)我的许多代码使用在版本之间不会改变的基本功能。无论哪种情况,我都想出了一种在代码中使用项目、解决方案或系统范围的版本定义的方法。这随后允许代码自动链接到正确的版本,并且可以(如果确实确定的话)检测并执行安装的 opencv 版本的正确代码,从而解决您的问题。 虽然您的方法在处理编译问题时很好且易于实施,但很难找到所有影响您的程序的小更改而不导致程序崩溃。我的第一个例子真的很难找到,因为它可以编译、运行,它会影响图像,但是以一种微妙的不同方式。而且你会很头疼发现这样的错误【参考方案2】:

我已经通过合并以下文章制定了一个让代码在各种版本的 OPENCV 上运行的解决方案:

    How to make a string out of macros Concatenating strings in macros Pragma statements in #defines 和 support for VS2008 here on MSDN 奖金:How to have global settings defined in a solution

如上所述,如果您在不兼容的版本之间弹出,这可能会导致一些严重的问题,但对于那些支持的版本和功能,这可能对某些人有用。使用此技术设置一次 opencv 版本,并让您的代码自动链接到所需的版本

    在源代码的一处定义 OPENCV_VERSION

    在属性表中定义它 在系统环境变量中定义它。

我的代码最终是这样的:

#include <iostream>

// #define OPENCV_VERSION $(OPENCV_VERSION)
// #define OPENCV_VERSION 220

#define QUOTE(name) #name
#define STR(macro) QUOTE(macro) 

#define LINK_TO_OPENCV(libname) __pragma(comment(lib, "opencv_" #libname STR(OPENCV_VERSION)))
#define LINK_TO_OPENCV_DEBUG(libname) __pragma(comment(lib, "opencv_" #libname STR(OPENCV_VERSION) "d"))

#ifndef NDEBUG
LINK_TO_OPENCV_DEBUG("core")
LINK_TO_OPENCV_DEBUG("highgui")
LINK_TO_OPENCV_DEBUG("imgproc")
#else
LINK_TO_OPENCV("core")
LINK_TO_OPENCV("highgui")
LINK_TO_OPENCV("imgproc")
#endif 


int main()

    std::cout << STR(LINK_TO_OPENCV("core")) << "\n";
    return 0;

现在可以在任何你喜欢的地方设置 OPENCV_VERSION。例如,您可以让每个人都包含一个包含以下行的头文件:

#define OPENCV_VERSION 220

或者您可以转到 Project->Properties->C/C++->Preprocessor 并将 Preprocessor Definitions 设置为 OPENCV_VERSION=220。 或者您可以在整个解决方案的共享属性表中执行相同的操作。

,这很重要,您可以使用此技术在 Windows 本身中定义一个名为 OPENCV_VERSION_ENV 的全局环境变量,并将其值设置为版本代码(例如 220)。然后您可以将预处理器定义设置为OPENCV_VERSION=$(OPENCV_VERSION_ENV),并将环境变量引入链接命令。您不能使用#define OPEN_VERSION $(OPENCV_VERSION_ENV),但由于属性页会自动转换 $(macros),因此我们可以在那里获取环境变量。

【讨论】:

哦,在 modules/core/include/opencv2/core/version.hpp 中已经有一个类似的结构 @berak 这是一个很好的评论。我们可以使用它以更好的方式定义 OPENCV_VERSION:#define OPENCV_VERSION CVAUX_STR(CV_MAJOR_VERSION)CVAUX_STR(CV_MINOR_VERSION)CVAUX_STR(CV_SUBMINOR_VERSION)

以上是关于自动包含不同版本的 OpenCV 库的主要内容,如果未能解决你的问题,请参考以下文章

Opencv不同版本与visual studio2013的环境配置

libopencvso文件大小

怎么使用CMake链接不同版本的第三方库

如何在qmake中设置libs顺序?

如何在 Eclipse 中为交叉编译项目有条件地包含两个相同版本的不同名称库?

VSLAM依赖库版本配置(CMake)