I've been automatically including the opencv library files for my c++ code on Visual Studio 2008 on Windows 7 with the following code:
#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
but I run into trouble when the system has a different version of the opencv library installed because the .lib files have the version (in this case, 2.31) in the filename. Is there a good way to automatically or near-automatically detect what version of the opencv library is available then slide in the appropriate version string into the pragma?
I have worked out a solution to having code run on various versions of OPENCV by merging the following articles:
As noted, this can cause some serious grief if you pop between incompatible versions but for those versions and features supported this may be useful to some. Use this technique to set the opencv version once and have your code automatically link to the desired version by either
My code ended up like so:
#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;
}
And now to set the OPENCV_VERSION anywhere you like. For example, you can have a single header file included by everyone that has the line:
#define OPENCV_VERSION 220
Or you can goto Project->Properties->C/C++->Preprocessor and set Preprocessor Definitions to OPENCV_VERSION=220. Or you can do the same thing in a shared property sheet for the entire solution.
Or, and this is important, you can use this technique to define a global environment variable in windows itself called OPENCV_VERSION_ENV and set its value to the version code (say, 220). Then you can put set the preprocessor definition to OPENCV_VERSION=$(OPENCV_VERSION_ENV)
and you will bring in the environment variable into the link command. You CANNOT do a #define OPEN_VERSION $(OPENCV_VERSION_ENV)
but since the property pages will automatically translate $(macros) we can get environment variables there.
#define OPENCV_VERSION CVAUX_STR(CV_MAJOR_VERSION)CVAUX_STR(CV_MINOR_VERSION)CVAUX_STR(CV_SUBMINOR_VERSION)
Steve 2013-02-20 20:19
There are small changes between different OpenCV versions - not much, but enough to crash your app when you change from 2.0 to 2.2 or from 2.2 to 2.3.1. Also, the beta 2.4 release has enough changes from previous ones.
So best is to test your app with an OpenCV version, and deliver it with those dlls only.
A small example:
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.
The corresponding 2.2 call would be
a.setTo(Scalar::all(10));
Or
a = 0; // runs fine on 2.3.1. Equivalent to setTo().
// Does not compile on earlier versions
Another example is cv::drawPoly()
, which has a different signature on 2.2 and 2.3.1.
Given the fact that those changes are not well documented, the chance to miss one of them by mistake is really high.