OpenCV 在Windows中安装
此处的描述在Windows 7 SP1上进行了测试。然而,它也应该适用于任何其他相对现代的Windows操作系统。
如果您按照以下步骤后遇到错误,请随时通过OpenCV Q&A论坛与我们联系。我们将竭尽全力帮助您。
注意
要使用OpenCV库,您有两个选项:通过使用预构建库进行安装或通过从源文件创建自己的库进行安装。虽然第一个更容易完成,但只有当您使用最新的Microsoft Visual Studio IDE进行编码时,才能使用它,并且不会利用我们集成到我们的库中的最先进的技术。.. _Windows_Install_Prebuild:
使用预构建的库进行安装
- 启动一个首选的网页浏览器,并转到我们的Sourceforge页面。
- 选择一个你想要使用和下载它的构建。
- 确保您具有管理员权限。解压缩自解压存档。
- 您可以在所选路径上检查安装,如下所示。
通过从源文件制作自己的库来进行安装
您可以在以下视频中找到本教程的内容:托管在YouTube上的第1 部分和第2部分。
警告
以上这些视频已经过时,包含不准确的信息。请注意,由于这些视频中描述的解决方案不再受支持,甚至可能会中断您的安装。
如果您正在构建自己的库,则可以从Git存储库获取源文件。
从头构建OpenCV库需要预先安装几个工具:
- 一个IDE的选择(最好),或者只是一个CC ++编译器,实际上会使二进制文件。这里我们将使用Microsoft Visual Studio。但是,您可以使用任何其他具有有效CC ++编译器的IDE。
- CMake,它是一个整洁的工具,用于从OpenCV源文件制作项目文件(对于您选择的IDE)。它还将允许轻松配置OpenCV构建文件,以便使二进制文件完全符合您的需要。
- Git获取OpenCV源文件。一个很好的工具是TortoiseGit。或者,您可以从我们的Sourceforge页面下载源文件的归档版本
OpenCV可能会有多种口味。有一个“核心”部分将自行工作。然而,有几种工具,由第三方提供的图书馆提供OpenCV可能利用的服务。这些将在许多方面提高其能力。为了使用任何一个,您需要在系统上下载并安装它们。
- 在Python库都需要建立Python接口的OpenCV。现在使用版本2.7.{x}。如果要构建OpenCV文档,这也是必须的。
- Numpy是Python的科学计算软件包。需要Python接口。
- 英特尔线程构建块(TBB)在OpenCV中用于并行代码片段。使用此功能将确保OpenCV库将充分利用系统CPU中的所有核心。
- 英特尔®集成性能原语(IPP)可用于提高OpenCV库的颜色转换,Haar培训和DFT功能的性能。注意,因为这不是免费的服务。
- Intel IPP异步C / C ++目前专注于为高级图像处理和计算机视觉功能提供英特尔图形支持。
- OpenCV通过使用Qt框架,提供了比起默认的图形用户更有用的界面。要快速了解这些内容,请查看文档highgui模块,在Qt新功能部分下。需要版本4.6或更高版本的框架。
- Eigen是线性代数的C ++模板库。
- 最新的CUDA工具包将允许您使用GPU内部的电源。这将大大提高某些算法的性能(例如HOG描述符)。越来越多的我们的算法在GPU上工作是OpenCV团队不断的努力。
- 库需要OpenEXR源文件才能使用这种高动态范围(HDR)图像文件格式。
- OpenNI框架包含一组开源API,通过诸如语音命令识别,手势和身体运动跟踪等方法,提供对设备自然交互的支持。预制二进制文件可以在这里找到。OpenNI和OpenNI2的源代码也可以在Github上使用。
- Doxygen是一个文档生成器,是实际创建OpenCV文档的工具。
现在我们将描述完整的构建步骤(使用所有上述框架,工具和库)。如果您不需要其中的一些支持,您可以随意跳过本节。
建立library
- 确保你有一个工作的IDE与一个有效的编译器。如果Microsoft Visual Studio只是安装它并确保它启动。
- 安装CMake的。只需按照向导,不需要将其添加到路径。默认安装选项可以。
- 从其官方网站下载并安装最新版本的msysgit 。还有便携式版本,您只需解压即可访问控制台版本的Git。假设对于我们中的一些人来说,这可能是足够的。
- 安装TortoiseGit。根据您工作的操作系统的类型选择32位或64位版本。安装时,找到您的msysgit(如果不自动)。按照向导 - 大部分默认选项都可以。
- 在文件系统中选择一个目录,您将在其中下载OpenCV库。我建议创建一个新的,具有短路径,没有特殊字符,例如D:/OpenCV。对于本教程,我将建议您这样做。如果你使用自己的路径知道你在做什么 - 这是可以的。将存储库克隆到所选目录。单击克隆按钮后,将出现一个窗口,您可以从中选择要从哪个存储库下载源文件(https://github.com/opencv/opencv.git)以及什么目录(D:/OpenCV)。按OK按钮,耐心等候,因为存储库是相当沉重的下载。根据您的互联网连接需要一些时间。
- 在本节中,我将介绍如何安装第三方库。
- 下载Python库并使用默认选项进行安装。您将需要一些其他python扩展。幸运的是安装所有这些可以通过一个名为Setuptools的好工具进行自动化。再次下载并安装。
- 安装Numpy最简单的方法是从sourceforge页面下载其二进制文件。确保您的下载并安装完整的python版本的二进制(所以版本2.7)。
- 对于英特尔线程构建块(TBB),请下载源文件并将其解压缩到系统上的目录中。例如让我们来D:/OpenCV/dep。为了安装Intel Integrated Performance Primitives(IPP),故事是一样的。为了提取档案,我建议您使用7-Zip应用程序。
- 对于Intel IPP异步C / C ++下载源文件并设置环境变量IPP_ASYNC_ROOT。应该指出<your Program Files(x86) directory>/Intel/IPP Preview /ipp directory。这里表示特定的预览名称。
- 在Eigen库的情况下,再次下载并提取到D:/OpenCV/dep目录的情况。
- 与OpenEXR相同。
- 对于OpenNI Framework,您需要安装开发版本和PrimeSensor模块。
- 对于CUDA,您需要再次使用两个模块:最新的CUDA Toolkit和CUDA Tools SDK。根据您的操作系统,使用32位或64位安装程序,通过完整的选项下载并安装它们两者。
- 在Qt框架的情况下,您需要构建二进制文件(除非您使用带有32位编译器的Microsoft Visual Studio 2008)。为此,请访问Qt下载页面。下载源文件(不是安装程序!!!):
解压缩到是个不错的短命名的目录中D:/OpenCV/dep/qt/。那么你需要建立它。启动一个视觉 工作室 命令 提示符(2010)通过开始菜单的搜索(或通过开始菜单导航所有程序- >微软的Visual Studio 2010 - > Visual Studio工具- > Visual Studio命令提示符(2010))。
现在导航到提取的文件夹并使用此控制台窗口进入它。您应该有一个文件夹包含安装,Make等文件。使用dir命令列出当前目录中的文件。一旦到达此目录,输入以下命令:
configure.exe -release -no-webkit -no-phonon -no-phonon-backend -no-script -no-scripttools
-no-qt3support -no-multimedia -no-ltcg
完成这个将需要大约10-20分钟。然后输入下一个需要更长时间的命令(可以轻松占用一整个小时):
NMAKE
之后,在Windows 7上使用以下命令设置Qt环境变量:
setx -m QTDIR D:/OpenCV/dep/qt/qt-everywhere-opensource-src-4.7.3
另外,使用PathEditor将内置的二进制文件路径添加到系统路径。在我们这种情况下D:/OpenCV/dep/qt/qt-everywhere-opensource-src-4.7.3/bin。
- 注意如果您打算进行Qt应用程序开发,您还可以在此安装Qt Visual Studio加载项。之后,您可以制作和构建Qt应用程序,而无需使用Qt Creator。一切都很好地集成到Visual Studio中。
7、现在启动CMake(cmake-gui)。您可以在开始菜单搜索中再次输入,也可以从所有程序 - > CMake 2.8 - > CMake(cmake-gui)中获取。首先,选择OpenCV库源文件的目录(1)。然后,指定要在其中构建OpenCV(2)的二进制文件的目录。
按配置按钮指定要使用的编译器(和IDE)。请注意,如果您可以在不同的编译器之间选择64位或32位库。选择您在应用程序开发中使用的那个。
CMake将开始,并根据您的系统变量尝试自动找到尽可能多的包。您可以修改用于在WITH - > WITH_X菜单点中构建的包(其中X是包的缩写)。以下是您可以打开或关闭的当前包的列表:
选择要使用的所有软件包,然后再次按配置按钮。有关构建选项的简要概述,请确保二进制目录选择下的分组选项已打开。对于某些包,CMake可能找不到所有必需的文件或目录。在这些情况下,CMake将在其输出窗口(位于GUI底部)发出错误,并将其字段值设置为未找到的常量。例如:
对于这些,您需要手动设置查询的目录或文件路径。再次按下“ 配置”按钮,查看您输入的值是否被接受。执行此操作直到所有条目都很好,并且您看不到GUI的字段/值或输出部分中的错误。现在我想强调一个您一定会喜欢的选项:ENABLE - > ENABLE_SOLUTION_FOLDERS。OpenCV将创建许多项目,并转动此选项将确保它们在解决方案资源管理器中的目录中分类。这是必须有的功能,如果你问我。
此外,您需要选择要构建的OpenCV的哪一部分。
- BUILD_DOCS - >它创建了两个用于构建OpenCV文档的项目(将有一个用于构建HTML和PDF文件的单独项目)。请注意,这些不是与解决方案一起构建的。您需要对它们进行明确的构建项目命令。
- BUILD_EXAMPLES - > OpenCV带有许多示例应用程序,您可以从中了解大多数库功能。如果OpenCV在您的计算机上完全正常运行,这样做也可轻松尝试。
- BUILD_PACKAGE - >在2.3之前,您可以构建一个将构建OpenCV安装程序的项目。这样,您可以轻松地在其他系统上安装OpenCV风味。对于OpenCV的最新源文件,它会生成一个新项目,只需使用OpenCV源创建一个zip存档。
- BUILD_SHARED_LIBS - >这样可以控制构建DLL文件(打开时)或静态库文件(* .lib)。
- BUILD_TESTS - > OpenCV的每个模块都有一个分配给它的测试项目。构建这些测试项目也是一个很好的尝试方式,模块的工作原理与您的系统一样。
- BUILD_PERF_TESTS - >还有许多OpenCV功能的性能测试。如果您关心性能,建立并运行。
- BUILD_opencv_python - >不言自明。创建使用Python语言的OpenCV的二进制文件。
再次按配置按钮,确保没有报告错误。如果是这种情况,可以通过按下“ 生成”按钮来告诉CMake创建项目文件。转到构建目录并打开创建的OpenCV解决方案。根据您选择的上述选项,您可以选择多少项目可能包含相当多的项目,以便在启动时可以在IDE上容忍。现在您需要同时构建Release和Debug二进制文件。使用IDE上的下拉菜单,在其中一个进行构建之后,更改其中的另一个。
最后,您可以观察bin目录中的内置二进制文件:
对于文档,您需要在doxygen项目上明确地发出构建命令,以获取HTML文档。它会叫Doxygen做所有的辛勤工作。您可以在其中找到生成的文档build/doc/doxygen/html。
要收集您将在自己的项目期间使用的标题和二进制文件到独立的目录(与预构建的二进制代码一样),您需要显式构建安装项目。
这将在Build中创建一个Install目录,将所有构建的二进制文件集合到一个位置。仅在构建版本和调试版本之后才能使用。
要测试您的构建,只需进入Build/bin/Debug或Build/bin/Release目录,并启动几个应用程序,如contours.exe。如果他们跑,你就完成了。否则,绝对会有一些错误。在这种情况下,您应该在我们的问答论坛上与我们联系。如果一切正常,contours.exe输出应类似于以下图像(如果使用Qt支持构建):
注意
如果您使用GPU模块(CUDA库),请确保您还升级到GPU的最新驱动程序。包含无效条目(或找不到)nvcuda.dll的错误消息主要由旧的视频卡驱动程序引起。要测试GPU(如果已经建立)运行performance_gpu.exe示例应用程序。
设置OpenCV环境变量并将其添加到系统路径
首先,我们设置一个环境变量来使我们的工作更容易。这将保存我们在项目中使用的OpenCV库的构建目录。启动命令窗口并输入:
setx -m OPENCV_DIR D:\OpenCV\Build\x86\vc11 (suggested for Visual Studio 2012 - 32 bit Windows)
setx -m OPENCV_DIR D:\OpenCV\Build\x64\vc11 (suggested for Visual Studio 2012 - 64 bit Windows)
setx -m OPENCV_DIR D:\OpenCV\Build\x86\vc12 (suggested for Visual Studio 2013 - 32 bit Windows)
setx -m OPENCV_DIR D:\OpenCV\Build\x64\vc12 (suggested for Visual Studio 2013 - 64 bit Windows)
setx -m OPENCV_DIR D:\OpenCV\Build\x64\vc14 (suggested for Visual Studio 2015 - 64 bit Windows)
这里的目录是您的OpenCV二进制文件(提取或构建)。您可以有不同的平台(例如x64而不是x86)或编译器类型,所以替换适当的值。在这里面,你应该有两个名为lib和bin的文件夹。如果您希望将计算机设置为智能,而不是用户明智,则应添加-m。
如果你建立了静态库,那么你就完成了。否则,您需要将bin文件夹路径添加到系统路径。这是因为您将以“动态链接库”(也称为DLL)的形式使用OpenCV库。在这些内存中存储OpenCV库所包含的所有算法和信息。操作系统只能在运行时根据需要加载它们。但是,要做到这一点,操作系统需要知道它们在哪里。系统PATH包含可以找到DLL的文件夹列表。将OpenCV库路径添加到此操作系统,如果他需要OpenCV二进制文件,操作系统将会知道在哪里看。否则,您将需要在应用程序可执行文件旁边复制使用过的DLL(exe)为操作系统找到它,这是非常不愉快的,如果你在许多项目上工作。要做到这一点再次启动PathEditor并添加以下新条目(在应用程序中右键单击以显示菜单):
%OPENCV_DIR%\ bin中
将其保存到注册表并完成。如果您更改了构建目录的位置,或者想要使用不同的构建来尝试应用程序,那么您需要做的就是通过命令窗口中的setx命令来更新OPENCV_DIR变量。
现在,您可以在“Microsoft Visual Studio”部分中使用OpenCV如何构建应用程序来继续阅读教程。您将在Microsoft Visual Studio IDE的帮助中找到如何在自己的项目中使用OpenCV库。
如何使用OpenCV在“Microsoft Visual Studio”中构建应用程序
我在这里描述的一切将适用于C\C++ OpenCV 的界面。我从假设你已经阅读并成功完成了Windows中的安装教程。因此,在您进一步之前,请确保您具有包含OpenCV头文件和二进制文件的OpenCV目录,并按照此处所述设置环境变量设置OpenCV环境变量并将其添加到系统路径。
由我们分发的Microsoft Windows操作系统上的OpenCV库位于动态链接库(DLL)中。这些优点是,库的所有内容只能在运行时按需加载,并且无数程序可能使用相同的库文件。这意味着如果您有十个使用OpenCV库的应用程序,则不需要为每个应用程序提供每个应用程序。当然,您需要在要运行应用程序的所有系统上安装OpenCV 的DLL。
另一种方法是使用具有lib扩展名的静态库。您可以通过使用我们的源文件来构建它们,如Windows中的“ 安装”教程中所述。当你使用这个库将内置在您的exe文件。因此,由于某些原因,用户将无法删除它们。作为一个缺点,您的应用程序将是更大的一个,因为它将需要更多的时间来加载它在启动期间。
要使用OpenCV构建应用程序,您需要做两件事情:
- 告诉编译器OpenCV库的外观。您可以通过显示头文件来执行此操作。
- 告诉链接器从何处获取OpenCV的功能或数据结构。
如果使用lib系统,则必须设置库文件所在的路径,并指定其中的哪一个。
在构建期间,链接器将查找这些库,并将所有使用的函数和数据结构的定义和实现添加到可执行文件中。
如果您使用DLL系统,则必须再次指定所有这些,但是由于其他原因。
这是一个Microsoft操作系统特定的东西。看来,链接器需要知道在DLL中哪里可以在运行时搜索数据结构或函数。
此信息存储在lib文件中。不过,它们不是静态库。它们是所谓的导入库。
这就是为什么当你在Windows中制作一些DLL时,你也会得到一些lib扩展库。很重要的是在运行时只需要DLL。
要将所有这些信息传递给Visual Studio IDE,您可以在全局范围内执行(所有未来的项目都将获得此信息)或本地(因此仅适用于当前项目)。全局的优势是你只需要做一次; 但是,所有这些信息都可能不合时宜地聚集所有的项目。在全局的情况下,如何执行此操作取决于您使用的Microsoft Visual Studio。有2008年和以前的版本和2010年的做法。在本教程的全局部分中,我将展示主要区别。
Visual Studio中项目的基础项目是一个解决方案。解决方案可能包含多个项目。项目是应用程序的构建块。每个项目都会实现一些东西,你将有一个主要的项目,你可以把这个项目的难题放在一起。在许多简单的应用程序(如许多教程将是)的情况下,您不需要将应用程序分解为模块。在这些情况下,您的主要项目将是唯一的现有项目。现在,通过File - > New - > Project菜单选项,在Visual Studio中创建一个新的解决方案。选择Win32控制台应用程序作为类型。输入其名称并选择要创建它的路径。然后在即将到来的对话框中确保创建一个空项目。
The local method
每个项目都是与其他项目分开构建的。由于这个每个项目都有自己的规则包。在这个规则中,包中存储了IDE需要知道的所有信息来构建项目。对于任何应用程序,至少有两种构建模式:发布和调试。在调试有许多功能,存在,因此,你可以找到并解决您的应用程序中更容易错误。相比之下,Release是一个优化的版本,其目标是使应用程序尽可能快地运行或尽可能小。您可能会认为,这些模式在构建期间也需要使用不同的规则。因此,每个构建模式都存在不同的规则包。这些规则包在IDE中作为项目属性调用,您可以使用Property Manager查看和修改它们。您可以使用View - > Property Pages(对于Visual Studio 2013起,进入View - > Other Windows - > Property Manager)。展开它,您可以看到现有的规则包(称为属性表)。
这些真正有用的东西是您可以创建一个规则包一次,然后可以将其添加到新的项目中。创建一次并稍后重用。我们要创建一个新的属性表,其中包含编译器和链接器需要知道的所有规则。当然,我们将需要一个单独的调试和发布版本。启动调试一,如下图所示:
使用OpenCV_Debug名称。然后选择表格右键 - >属性。在下面我将展示在本地设置OpenCV规则,因为我发现不必用不使用自定义规则来污染项目。去C ++组通用条目和“其他包含目录”添加OpenCV包含的路径。如果没有“C / C ++”组,则应该将任何.c / .cpp文件添加到项目中。
$(OPENCV_DIR)\include
当添加第三方库设置时,通常使用环境变量背后的权力是一个好主意。OpenCV库的完整位置可能会在每个系统上更改。此外,由于某些原因,您甚至可能会自动移动安装目录。如果您在属性表中给出明确的路径,那么当您将其进一步传递给具有不同OpenCV安装路径的其他人时,您的项目将最终不起作用。此外,修复这将需要手动修改每个显式路径。一个更优雅的解决方案是使用环境变量。任何您放入括号内的任何以美元符号开头的内容将在运行时替换为当前环境变量值。这里介绍了我们以前的教程中已经做出的环境变量设置OpenCV环境变量并将其添加到系统路径。
下一步去链接器 - >常规下的“附加库目录”添加libs目录:
$(OPENCV_DIR)\ LIB
然后,您需要指定链接器应查看的库。要执行此操作,请转到链接器 - >输入,并在“附加依赖关系”条目下添加要使用的所有模块的名称:
the libraries的命名如下:
opencv_(The Name of the module)(The version Number of the library you use)d.lib
完整列表,最新版本将包含:
opencv_calib3d300d.lib
opencv_core300d.lib
opencv_features2d300d.lib
opencv_flann300d.lib
opencv_highgui300d.lib
opencv_imgcodecs300d.lib
opencv_imgproc300d.lib
opencv_ml300d.lib
opencv_objdetect300d.lib
opencv_photo300d.lib
opencv_shape300d.lib
opencv_stitching300d.lib
opencv_superres300d.lib
opencv_ts300d.lib
opencv_video300d.lib
opencv_videoio300d.lib
opencv_videostab300d.lib
最后的字母d表示这些是调试所需的库。现在点击确定保存,并在发布规则部分内使用新的属性。确保省略库名称中的d个字母,并保存属性表与其上方的保存图标。
您可以在项目目录中找到属性表。在这一点上,无论何时创建OpenCV项目,将它们备份到一些特殊的目录中,以便在将来随时随地掌握它,这是一个明智的决定。请注意,对于Visual Studio 2010,文件扩展名是道具,而在2008年,这是vsprops。
下一次当您创建一个新的OpenCV项目时,只需使用属性管理器中的“添加现有属性表...”菜单条目即可轻松添加OpenCV构建规则。
The global method
如果您发现将属性页面添加到每个项目中都太麻烦,您还可以将此规则添加到“全局属性页”。但是,这仅适用于附加的include和library目录。使用的库的名称仍然需要通过使用例如:属性页手动指定。
在Visual Studio 2008中,您可以在“工具” - >“选项” - >“项目和解决方案” - >“VC ++目录”下找到该文件。
在Visual Studio 2010中,它已被移动到全局属性表,该属性表会自动添加到您创建的每个项目中:
该过程与本地方法的情况相同。只需使用环境变量OPENCV_DIR添加包含目录。
Test it!
现在尝试下载我们的小测试源代码,或从OpenCV源的示例代码文件夹中获取。将其添加到您的项目并构建它。以下是其内容:
#include <opencv2/core.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/highgui.hpp>
#include <iostream>
using namespace cv;
using namespace std;
int main( int argc, char** argv )
{
if( argc != 2)
{
cout <<" Usage: display_image ImageToLoadAndDisplay" << endl;
return -1;
}
Mat image;
image = imread(argv[1], IMREAD_COLOR); // Read the file
if( image.empty() ) // Check for invalid input
{
cout << "Could not open or find the image" << std::endl ;
return -1;
}
namedWindow( "Display window", WINDOW_AUTOSIZE ); // Create a window for display.
imshow( "Display window", image ); // Show our image inside it.
waitKey(0); // Wait for a keystroke in the window
return 0;
}
或者使用以下代码:
// Video Image PSNR and SSIM
#include <iostream> // for standard I/O
#include <string> // for strings
#include <iomanip> // for controlling float print precision
#include <sstream> // string to number conversion
#include <opencv2/imgproc/imgproc.hpp> // Gaussian Blur
#include <opencv2/core/core.hpp> // Basic OpenCV structures (cv::Mat, Scalar)
#include <opencv2/highgui/highgui.hpp> // OpenCV window I/O
using namespace std;
using namespace cv;
double getPSNR ( const Mat& I1, const Mat& I2);
Scalar getMSSIM( const Mat& I1, const Mat& I2);
void help()
{
cout
<< "\n--------------------------------------------------------------------------" << endl
<< "This program shows how to read a video file with OpenCV. In addition, it tests the"
<< " similarity of two input videos first with PSNR, and for the frames below a PSNR " << endl
<< "trigger value, also with MSSIM."<< endl
<< "Usage:" << endl
<< "./video-source referenceVideo useCaseTestVideo PSNR_Trigger_Value Wait_Between_Frames " << endl
<< "--------------------------------------------------------------------------" << endl
<< endl;
}
int main(int argc, char *argv[], char *window_name)
{
help();
if (argc != 5)
{
cout << "Not enough parameters" << endl;
return -1;
}
stringstream conv;
const string sourceReference = argv[1],sourceCompareWith = argv[2];
int psnrTriggerValue, delay;
conv << argv[3] << argv[4]; // put in the strings
conv >> psnrTriggerValue >> delay;// take out the numbers
char c;
int frameNum = -1; // Frame counter
VideoCapture captRefrnc(sourceReference),
captUndTst(sourceCompareWith);
if ( !captRefrnc.isOpened())
{
cout << "Could not open reference " << sourceReference << endl;
return -1;
}
if( !captUndTst.isOpened())
{
cout << "Could not open case test " << sourceCompareWith << endl;
return -1;
}
Size refS = Size((int) captRefrnc.get(CV_CAP_PROP_FRAME_WIDTH),
(int) captRefrnc.get(CV_CAP_PROP_FRAME_HEIGHT)),
uTSi = Size((int) captUndTst.get(CV_CAP_PROP_FRAME_WIDTH),
(int) captUndTst.get(CV_CAP_PROP_FRAME_HEIGHT));
if (refS != uTSi)
{
cout << "Inputs have different size!!! Closing." << endl;
return -1;
}
const char* WIN_UT = "Under Test";
const char* WIN_RF = "Reference";
// Windows
namedWindow(WIN_RF, CV_WINDOW_AUTOSIZE );
namedWindow(WIN_UT, CV_WINDOW_AUTOSIZE );
cvMoveWindow(WIN_RF, 400 , 0); //750, 2 (bernat =0)
cvMoveWindow(WIN_UT, refS.width, 0); //1500, 2
cout << "Frame resolution: Width=" << refS.width << " Height=" << refS.height
<< " of nr#: " << captRefrnc.get(CV_CAP_PROP_FRAME_COUNT) << endl;
cout << "PSNR trigger value " <<
setiosflags(ios::fixed) << setprecision(3) << psnrTriggerValue << endl;
Mat frameReference, frameUnderTest;
double psnrV;
Scalar mssimV;
while( true) //Show the image captured in the window and repeat
{
captRefrnc >> frameReference;
captUndTst >> frameUnderTest;
if( frameReference.empty() || frameUnderTest.empty())
{
cout << " < < < Game over! > > > ";
break;
}
++frameNum;
cout <<"Frame:" << frameNum;
///////////////////////////////// PSNR ////////////////////////////////////////////////////
psnrV = getPSNR(frameReference,frameUnderTest); //get PSNR
cout << setiosflags(ios::fixed) << setprecision(3) << psnrV << "dB";
//////////////////////////////////// MSSIM /////////////////////////////////////////////////
if (psnrV < psnrTriggerValue)
{
mssimV = getMSSIM(frameReference,frameUnderTest);
cout << " MSSIM: "
<< "R" << setiosflags(ios::fixed) << setprecision(3) << mssimV.val[2] * 100
<< "G" << setiosflags(ios::fixed) << setprecision(3) << mssimV.val[1] * 100
<< "B" << setiosflags(ios::fixed) << setprecision(3) << mssimV.val[0] * 100;
}
cout << endl;
////////////////////////////////// Show Image /////////////////////////////////////////////
imshow( WIN_RF, frameReference);
imshow( WIN_UT, frameUnderTest);
c = cvWaitKey(delay);
if (c == 27) break;
}
return 0;
}
double getPSNR(const Mat& I1, const Mat& I2)
{
Mat s1;
absdiff(I1, I2, s1); // |I1 - I2|
s1.convertTo(s1, CV_32F); // cannot make a square on 8 bits
s1 = s1.mul(s1); // |I1 - I2|^2
Scalar s = sum(s1); // sum elements per channel
double sse = s.val[0] + s.val[1] + s.val[2]; // sum channels
if( sse <= 1e-10) // for small values return zero
return 0;
else
{
double mse =sse /(double)(I1.channels() * I1.total());
double psnr = 10.0*log10((255*255)/mse);
return psnr;
}
}
Scalar getMSSIM( const Mat& i1, const Mat& i2)
{
const double C1 = 6.5025, C2 = 58.5225;
/***************************** INITS **********************************/
int d = CV_32F;
Mat I1, I2;
i1.convertTo(I1, d); // cannot calculate on one byte large values
i2.convertTo(I2, d);
Mat I2_2 = I2.mul(I2); // I2^2
Mat I1_2 = I1.mul(I1); // I1^2
Mat I1_I2 = I1.mul(I2); // I1 * I2
/*************************** END INITS **********************************/
Mat mu1, mu2; // PRELIMINARY COMPUTING
GaussianBlur(I1, mu1, Size(11, 11), 1.5);
GaussianBlur(I2, mu2, Size(11, 11), 1.5);
Mat mu1_2 = mu1.mul(mu1);
Mat mu2_2 = mu2.mul(mu2);
Mat mu1_mu2 = mu1.mul(mu2);
Mat sigma1_2, sigma2_2, sigma12;
GaussianBlur(I1_2, sigma1_2, Size(11, 11), 1.5);
sigma1_2 -= mu1_2;
GaussianBlur(I2_2, sigma2_2, Size(11, 11), 1.5);
sigma2_2 -= mu2_2;
GaussianBlur(I1_I2, sigma12, Size(11, 11), 1.5);
sigma12 -= mu1_mu2;
///////////////////////////////// FORMULA ////////////////////////////////
Mat t1, t2, t3;
t1 = 2 * mu1_mu2 + C1;
t2 = 2 * sigma12 + C2;
t3 = t1.mul(t2); // t3 = ((2*mu1_mu2 + C1).*(2*sigma12 + C2))
t1 = mu1_2 + mu2_2 + C1;
t2 = sigma1_2 + sigma2_2 + C2;
t1 = t1.mul(t2); // t1 =((mu1_2 + mu2_2 + C1).*(sigma1_2 + sigma2_2 + C2))
Mat ssim_map;
divide(t3, t1, ssim_map); // ssim_map = t3./t1;
Scalar mssim = mean( ssim_map ); // mssim = average of ssim map
return mssim;
}
您可以从两个地方启动Visual Studio构建。从IDE(键盘组合:Control-F5)或通过导航到您的构建目录并双击启动应用程序。抓住的是这两个不一样。当您从IDE启动它的当前工作目录是项目目录,否则它是应用程序文件当前的文件夹(通常是您的构建目录)。此外,如果从IDE启动,控制台窗口一旦完成就不会关闭。它会等待你的击键。
当您在代码中打开代码并保存命令时,这一点很重要。您的资源将相对于您的工作目录保存(并查询打开!!!)。这是除非您给出一个完整的,显式的路径作为I / O功能的参数。在上面的代码中,我们打开了OpenCV标志。启动应用程序之前,请确保将映像文件放在当前的工作目录中。修改代码中的图像文件名,以便在其他图像上进行尝试。运行它并且voá:
Visual Studio的命令行参数
在我们将来的一些教程中,您将看到程序主输入法将通过给出一个运行时参数。为此,您可以启动命令窗口(在开始菜单中为cmd + Enter),导航到可执行文件并使用参数启动它。所以例如在我的上层项目的情况下,这将是:
D:
CD OpenCV \ MySolutionName \ Release
MySolutionName.exe exampleImage.jpg
在这里,我首先改变了我的驱动器(如果您的项目不在OS本地驱动器上),则导航到我的项目并以示例图像参数启动它。而在Linux系统下,常见的是微软Windows上的控制台窗口,很多人几乎从不使用它。此外,在测试您的应用程序时,一次又一次添加相同的参数,这在某种程度上是一个繁琐的任务。幸运的是,在Visual Studio中有一个菜单可以自动化所有这些:
在这里指定输入的名称,当您从Visual Studio环境启动应用程序时,您将自动参数传递。在下一个介绍性教程中,您将看到对源代码较高的深入解释:加载和显示图像。
OpenCV 图像加载和显示
目标
在本教程中,您将学习如何:
- 加载图像(使用cv :: imread)
- 创建一个名为OpenCV的窗口(使用cv :: namedWindow)
- 在OpenCV窗口中显示图像(使用cv :: imshow)
源代码
从这里下载源代码。
#include <opencv2/core.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/highgui.hpp>
#include <iostream>
#include <string>
using namespace cv;
using namespace std;
int main( int argc, char** argv )
{
String imageName( "../data/HappyFish.jpg" ); // by default
if( argc > 1)
{
imageName = argv[1];
}
Mat image;
image = imread( imageName, IMREAD_COLOR ); // Read the file
if( image.empty() ) // Check for invalid input
{
cout << "Could not open or find the image" << std::endl ;
return -1;
}
namedWindow( "Display window", WINDOW_AUTOSIZE ); // Create a window for display.
imshow( "Display window", image ); // Show our image inside it.
waitKey(0); // Wait for a keystroke in the window
return 0;
}
代码链接:点击进入
说明
在OpenCV 2中,我们有多个模块。每个人负责处理不同的区域或方法。您可以在这些教程本身的用户指南的结构中观察到这一点。在您使用其中任何一个之前,您首先需要包含声明每个单独模块内容的头文件。
你几乎总是最终使用:
- 核心部分,这里定义了图书馆的基本构建块
- highgui模块,因为它包含输入和输出操作的功能
#include < opencv2 / core.hpp >
#include < opencv2 / imgcodecs.hpp >
#include < opencv2 / highgui.hpp >
#include <iostream>
#include <string>
我们还包括iostream,以方便控制台线路输出和输入。为了避免与其他库的数据结构和函数名冲突,OpenCV有自己的命名空间:cv。为了避免在每个这些cv ::关键字之前附加需要,您可以使用以下行在整个文件中导入命名空间:
using namespace cv;
对于STL库也是如此(用于控制台I / O)。现在,我们分析一下主要功能。我们开始确保从命令行获取有效的图像名称参数。否则默认拍照:“HappyFish.jpg”。
String imageName( "../data/HappyFish.jpg" ); // by default
if( argc > 1)
{
imageName = argv[1];
}
然后创建一个Mat对象,它将存储加载的图像的数据。
Mat image;
现在我们调用加载第一个参数(argv [1])指定的映像名称的cv :: imread函数。第二个参数指定了我们想要的图像的格式。这可能是:
- IMREAD_UNCHANGED(<0)按原样加载图像(包括alpha通道(如果存在)
- IMREAD_GRAYSCALE(0)将图像作为强度加载
- IMREAD_COLOR(> 0)以RGB格式加载图像
image = imread( imageName, IMREAD_COLOR ); // Read the file
- 注意OpenCV支持图像格式Windows位图(bmp),便携式图像格式(pbm,pgm,ppm)和Sun光栅(sr,ras)。在插件的帮助下(您需要指定使用它们,如果您建立自己的库,但是在我们出货的包中,默认情况下)您也可以加载像JPEG(jpeg,jpg,jpe),JPEG 2000(jp2 - 代号为CMake的Jasper),TIFF文件(tiff,tif)和便携式网络图形(png)。此外,OpenEXR也是一种可能性。
检查图像数据是否正确加载后,我们要显示图像,因此我们使用cv :: namedWindow函数创建一个OpenCV窗口。创建OpenCV后,它们将自动进行管理。为此,您需要指定其名称,以及如何从大小角度处理其包含的图像的更改。可能是:
- 如果不使用Qt后端,WINDOW_AUTOSIZE是唯一支持的。在这种情况下,窗口大小将占据显示的图像的大小。不允许调整大小!
- WINDOW_NORMAL在Qt你可以使用它来允许窗口调整大小。图像将根据当前窗口大小自行调整大小。通过使用| 操作员还需要指定是否希望图像保持其宽高比(WINDOW_KEEPRATIO)(WINDOW_FREERATIO)。
namedWindow( "Display window", WINDOW_AUTOSIZE ); // Create a window for display.
最后,要使用新的图像更新OpenCV窗口的内容,请使用cv :: imshow函数。指定要更新的OpenCV窗口名称和此操作期间要使用的映像:
imshow( "Display window", image ); // Show our image inside it.
因为我们希望我们的窗口被显示直到用户按下一个键(否则程序会结束太快),所以我们使用cv :: waitKey函数,其唯一的参数是等待用户输入需要多长时间毫秒)。零意味着永远等待。
waitKey(0); // Wait for a keystroke in the window
结果
- 编译代码,然后运行可执行文件,将图像路径作为参数。如果你在Windows上,可执行文件当然也会包含一个exe扩展名。当然确保图像文件靠近你的程序文件。
./DisplayImage HappyFish.jpg
- 你应该得到一个漂亮的窗口,如下所示:
OpenCV 图像加载,修改和保存
- 注意我们假设现在你知道如何使用cv :: imread加载图像并将其显示在窗口中(使用cv :: imshow)。阅读加载和显示图像教程否则。
目标
在本教程中,您将学习如何:
- 使用cv :: imread加载图像
- 使用cv :: cvtColor将图像从BGR转换为灰度格式
- 将转换的图像保存在磁盘上的文件(使用cv :: imwrite)
代码
这里是:
#include <opencv2/opencv.hpp>
using namespace cv;
int main( int argc, char** argv )
{
char* imageName = argv[1];
Mat image;
image = imread( imageName, IMREAD_COLOR );
if( argc != 2 || !image.data )
{
printf( " No image data \n " );
return -1;
}
Mat gray_image;
cvtColor( image, gray_image, COLOR_BGR2GRAY );
imwrite( "../../images/Gray_Image.jpg", gray_image );
namedWindow( imageName, WINDOW_AUTOSIZE );
namedWindow( "Gray image", WINDOW_AUTOSIZE );
imshow( imageName, image );
imshow( "Gray image", gray_image );
waitKey(0);
return 0;
}
说明
- 我们首先使用位于由imageName给出的路径中的cv :: imread加载图像。对于这个例子,假设你正在加载BGR图像。
- 现在我们将把我们的图像从BGR转换成灰度格式。OpenCV有一个非常好的功能来做这种转换:
cvtColor( image, gray_image, COLOR_BGR2GRAY );
你可以看到,cv :: cvtColor作为参数:
源图像(图像)
目标图像(gray_image),我们将保存转换的图像。
一个附加参数,指示将执行什么样的转换。在这种情况下,我们使用COLOR_BGR2GRAY(因为cv :: imread在彩色图像的情况下具有BGR默认通道顺序)。
- 所以现在我们有我们的新的gray_image,并希望将其保存在磁盘上(否则在程序结束后会丢失)。为了保存它,我们将使用一个函数来解析cv :: imread:cv :: imwrite
imwrite(“../../images/Gray_Image.jpg”,gray_image);
这将节省我们的gray_image为Gray_Image.jpg在文件夹图像位于两个级别我的当前位置。
- 最后,我们来看看图片。我们创建两个窗口并使用它们来显示原始图像以及新的图像:
namedWindow( imageName, WINDOW_AUTOSIZE );
namedWindow( "Gray image", WINDOW_AUTOSIZE );
imshow( imageName, image );
imshow( "Gray image", gray_image );
- 程序的waitKey(0)函数调用添加到用户密钥按下后永远等待。
结果
当你运行你的程序你应该得到这样的东西:
如果你检查你的文件夹(在我的情况下图像),你应该有一个名为Gray_Image.jpg的新的.jpg文件:
使用OpenCV与biicode dependency manager
目标
在本教程中,您将学习如何:
- 开始使用OpenCV使用biicode。
- 在OpenCV中使用biicode开发自己的应用程序。
- 在OpenCV版本之间切换。
什么是biicode?
biicode解决并跟踪C / C ++项目中的依赖关系和版本兼容性。使用biicode 钩子功能,C ++和C中开始使用OpenCV是非常简单的。只需编写一个包含OpenCV标题,biicode将在您的计算机中检索和安装OpenCV并配置您的项目。
先决条件
- biicode。这是一个在任何操作系统上安装它的链接。
- Windows用户:任何Visual Studio版本(首选Visual Studio 12)。
说明
示例:使用OpenCV中的Objdetect模块检测图像中的面
一旦安装了biicode,请在您的终端/控制台执行:
$ bii init mycvproject
$ cd mycvproject
$ bii open diego / opencvex
Windows用户还执行:
$ bii cpp:configure -G“Visual Studio 12”
现在执行bii cpp:build构建项目。
- 注意这可能需要一段时间才能下载并构建OpenCV。但是,这只能在您的机器中下载到您的“user / .biicode”文件夹。如果OpenCV安装过程失败,您可以直接在那里删除“user / .biicode”中的OpenCV文件,然后重复。
$ bii cpp:build
在bin文件夹中找到您的二进制文件:
$ cd bin
$ ./diego_opencvex_main
$ ./diego_opencvex_mainfaces
开发自己的应用程序
biicode与源代码文件中的include标题一起使用,它读取它们并检索其数据库中的所有依赖项。所以就像键入一样简单:
#include“diego / opencv / opencv / cv.h”
在您的.cpp文件的标题。
要使用OpenCV启动新项目,请执行:
$ bii init mycvproject
$ cd mycvproject
下一行只需在“块”中创建一个myuser / myblock文件夹,其中包含一个简单的“Hello World” main.cpp。您也可以手动执行:
$ bii new myuser / myblock --hello = cpp
现在用您的应用程序代码替换block / myuser / myblock中的main.cpp内容。将包含作为:
#include“diego / opencv / opencv / cv.h”
如果输入:
$ bii deps
你会检查这opencv/cv.h是一个“未解决”的依赖。你可以找到它:
$ bii find
现在,你可以按照上述的方式bii cpp:configure和bii cpp:build你的项目。
要使用常规的include指令,请在biicode.conf文件中配置它们。让你的包括:
#include“opencv / cv.h”
并写在你的biicode.conf中:
[includes]
opencv/cv.h: diego/opencv
[requirements]
diego/opencv: 0
切换OpenCV版本
如果要根据OpenCV 2.4.10和3.0-beta尝试或开发应用程序,请在biicode.conf文件中更改应用程序,只需在以下操作中交替跟踪[requirements]:
[requirements]
diego/opencv: 0
用下面这个来代替:
[requirements]
diego/opencv(beta): 0
- 注意第一次切换到3.0-beta,也需要一段时间才能下载并构建3.0-beta版本。从那时起,您可以通过修改biicode.conf要求在版本之间来回更改。
查找hooks和examples::
- OpenCV 2.4.10
- OpenCV 3.0 beta
- 来自OpenCV的objdetect模块
这只是一个例子,它如何用biicode python hooks来完成。可能现在CMake文件重用是可能的biicode,它可能更好的实现它与CMake,以获得更多的控制OpenCV的构建。
结果和结论
使用biicode安装OpenCV对于任何操作系统都是直接的。
运行任何示例,就像您刚刚从OpenCV的objdetect模块一样,或者开发自己的应用程序。它只需要一个biicode.conf文件来使OpenCV库在您的计算机中工作。
OpenCV版本之间的切换也是可行的,也是轻松的。
对于有关biicode的任何疑问或进一步的信息,请在Stackoverflow,biicode的论坛或询问biicode,我们将很乐意为您提供帮助。
OpenCV过渡指南
变更概述
本文档面向希望将代码迁移到OpenCV 3.0的软件开发人员。
与2.4版本相比,OpenCV 3.0引入了许多新的算法和功能。一些模块已被重写,有些模块已经重组。虽然2.4中的大部分算法仍然存在,但接口可能不同。
本节介绍一般最显着的更改,所有细节和过渡操作的示例在文档的下一部分。
Contrib仓库
https://github.com/opencv/opencv_contrib
这是所有新的,实验的和非免费的算法的地方。与主库相比,支持小组没有受到太多的关注,但社区努力保持良好的状态。
要使用contrib存储库构建OpenCV ,请将以下选项添加到cmake命令中:
-DOPENCV_EXTRA_MODULES_PATH=<path-to-opencv_contrib>/modules
标题布局
在2.4中,所有头都位于相应的模块子文件夹(opencv2 / .hpp和all C风格的API定义已被移动到单独的标题(例如opencv2 / core / core_c.h)。
算法接口
一般算法使用模式已经改变了:现在它必须在包裹在智能指针cv :: Ptr的堆上创建。版本2.4允许堆栈和堆分配,直接或通过智能指针。
get和set方法已经从cv :: Algorithm类以及CV_INIT_ALGORITHM宏中删除。在3.0中,所有属性都已转换为getProperty / setProperty纯虚拟方法。因此,它是不是能够创建和使用CV ::算法通过名称实例(使用通用的算法::创建(字符串)方法),应该显式调用相应的工厂方法。
更改模块
- ml模块已被重写
- highgui模块已经分为几部分:imgcodecs,videoio和highgui本身
- features2d模块已被重组(某些功能检测器已被移动到opencv_contrib / xfeatures2d模块)
- 传统的,非自由的模块已被删除。一些算法已被移动到不同的位置,一些算法被完全重写或删除
- CUDA API已经更新(gpu模块 - >几个cuda模块,命名空间gpu - >命名空间cuda)
- OpenCL API已更改(ocl模块已被删除,单独的ocl :: implementation - > Transparent API)
- 其他一些方法和类已被重定位
过渡提示
本节通过实例介绍具体的操作。
准备2.4
在最新的2.4.11 OpenCV版本中进行的一些更改允许您准备当前的代码库进行迁移:
- cv :: makePtr函数现在可用
- opencv2 / .hpp头已创建
新标题布局
注意: OpenCV 3.0中进行了旨在简化迁移的更改,因此不需要以下说明,但建议。
- 更换旧模块标题的内含物
// old header
#include "opencv2/<module>/<module>.hpp"
// new header
#include "opencv2/<module>.hpp"
- 如果您的代码使用C API(cv函数,Cv结构或CV_枚举),请包含相应的_c.h头文件。虽然建议使用C ++ API,但大多数C函数仍然可以在单独的头文件(opencv2 / core / core_c.h,opencv2 / core / types_c.h,opencv2 / imgproc / imgproc_c.h等)中访问。
现代使用算法
- 必须使用cv :: makePtr函数或相应的静态工厂方法(如果可用)创建算法实例:
// good ways
Ptr<SomeAlgo> algo = makePtr<SomeAlgo>(...);
Ptr<SomeAlgo> algo = SomeAlgo::create(...);
其他方式已弃用:
// bad ways
Ptr<SomeAlgo> algo = new SomeAlgo(...);
SomeAlgo * algo = new SomeAlgo(...);
SomeAlgo algo(...);
Ptr<SomeAlgo> algo = Algorithm::create<SomeAlgo>("name");
- 应通过相应的虚拟方法访问算法属性,getSomeProperty / setSomeProperty,通用get / set方法已被删除:
// good way
double clipLimit = clahe->getClipLimit();
clahe->setClipLimit(clipLimit);
// bad way
double clipLimit = clahe->getDouble("clipLimit");
clahe->set("clipLimit", clipLimit);
clahe->setDouble("clipLimit", clipLimit);
- 删除initModule_()呼叫
机器学习模块
由于该模块已被重写,因此需要花费一些时间来适应您的软件。所有算法都位于单独的ml命名空间及其基类StatModel中。单独的SomeAlgoParams类已被替换为一组相应的getProperty / setProperty方法。
下表说明了2.4和3.0机器学习类之间的对应关系。
2.4 | 3.0 |
CvStatModel | |
CvNormalBayesClassifier | |
CvKNearest | |
CvSVM | |
CvDTree | |
CV升压 | |
CvGBTrees | 未实现 |
CvRTrees | |
CvERTrees | 未实现 |
EM | |
CvANN_MLP | |
未实现 | |
CvMLData |
虽然在3.0版中重写的ml算法可以让您从xml / yml文件中加载旧的训练模型,但预测过程中的偏差是可能的。
points_classifier.cpp示例中的以下代码段说明了模型训练过程中的差异:
using namespace cv;
// ======== version 2.4 ========
Mat trainSamples, trainClasses;
prepare_train_data( trainSamples, trainClasses );
CvBoost boost;
Mat var_types( 1, trainSamples.cols + 1, CV_8UC1, Scalar(CV_VAR_ORDERED) );
var_types.at<uchar>( trainSamples.cols ) = CV_VAR_CATEGORICAL;
CvBoostParams params( CvBoost::DISCRETE, // boost_type
100, // weak_count
0.95, // weight_trim_rate
2, // max_depth
false, //use_surrogates
0 // priors
);
boost.train( trainSamples, CV_ROW_SAMPLE, trainClasses, Mat(), Mat(), var_types, Mat(), params );
// ======== version 3.0 ========
Ptr<Boost> boost = Boost::create();
boost->setBoostType(Boost::DISCRETE);
boost->setWeakCount(100);
boost->setWeightTrimRate(0.95);
boost->setMaxDepth(2);
boost->setUseSurrogates(false);
boost->setPriors(Mat());
boost->train(prepare_train_data()); // 'prepare_train_data' returns an instance of ml::TrainData class
特征检测
一些算法(FREAK,BRIEF,SIFT,SURF)已被移动到opencv_contrib存储库,到xfeatures2d模块,xfeatures2d命名空间。他们的界面也被改变了(继承于cv::Feature2D基类)。
xfeatures2d模块类的列表:
- cv :: xfeatures2d :: BriefDescriptorExtractor - 用于计算简要描述符的类(2.4位置:features2d)
- cv :: xfeatures2d :: FREAK - 实现FREAK(Fast Retina Keypoint)关键点描述符的类(2.4位置:features2d)
- cv :: xfeatures2d :: StarDetector - 该类实现了CenSurE检测器(2.4位置:features2d)
- cv :: xfeatures2d :: SIFT - 使用Scale Invariant特征变换(SIFT)算法提取关键点和计算描述符的类(2.4位置:非自由)
- cv :: xfeatures2d :: SURF - 用于从图像中提取加速的强大功能的类(2.4位置:非自由)
需要执行以下步骤:
- 将opencv_contrib添加到编译过程中
- 包含opencv2/xfeatures2d.h标题
- 使用命名空间 xfeatures2d
- 用或替换operator()呼叫detect,compute或detectAndCompute如果需要
一些类现在使用一般方法detect,compute或detectAndCompute由Feature2D基类而不是自定义提供operator()
以下代码片段说明了区别(从video_homography.cpp示例):
using namespace cv;
// ====== 2.4 =======
#include "opencv2/features2d/features2d.hpp"
BriefDescriptorExtractor brief(32);
GridAdaptedFeatureDetector detector(new FastFeatureDetector(10, true), DESIRED_FTRS, 4, 4);
// ...
detector.detect(gray, query_kpts); //Find interest points
brief.compute(gray, query_kpts, query_desc); //Compute brief descriptors at each keypoint location
// ====== 3.0 =======
#include "opencv2/features2d.hpp"
#include "opencv2/xfeatures2d.hpp"
using namespace cv::xfeatures2d;
Ptr<BriefDescriptorExtractor> brief = BriefDescriptorExtractor::create(32);
Ptr<FastFeatureDetector> detector = FastFeatureDetector::create(10, true);
// ...
detector->detect(gray, query_kpts); //Find interest points
brief->compute(gray, query_kpts, query_desc); //Compute brief descriptors at each keypoint location
OpenCL的
所有专门的ocl实现都隐藏在一般的C ++算法接口之后。现在可以在运行时动态选择功能执行路径:CPU或OpenCL; 这个机制也被称为“透明API”。
新类cv :: UMat旨在以方便的方式隐藏与OpenCL设备的数据交换。
以下示例说明了API修改(来自OpenCV站点):
- OpenCL感知代码OpenCV-2.x
// initialization
VideoCapture vcap(...);
ocl::OclCascadeClassifier fd("haar_ff.xml");
ocl::oclMat frame, frameGray;
Mat frameCpu;
vector<Rect> faces;
for(;;){
// processing loop
vcap >> frameCpu;
frame = frameCpu;
ocl::cvtColor(frame, frameGray, BGR2GRAY);
ocl::equalizeHist(frameGray, frameGray);
fd.detectMultiScale(frameGray, faces, ...);
// draw rectangles …
// show image …
}
- OpenCL感知代码OpenCV-3.x
// initialization
VideoCapture vcap(...);
CascadeClassifier fd("haar_ff.xml");
UMat frame, frameGray; // the only change from plain CPU version
vector<Rect> faces;
for(;;){
// processing loop
vcap >> frame;
cvtColor(frame, frameGray, BGR2GRAY);
equalizeHist(frameGray, frameGray);
fd.detectMultiScale(frameGray, faces, ...);
// draw rectangles …
// show image …
}
CUDA
cuda模块已经分成几个较小的部分:
- cuda - CUDA加速计算机视觉
- cudaarithm - 矩阵运算
- cudabgsegm - 背景分割
- cudacodec - 视频编码/解码
- cudafeatures2d - 特征检测和描述
- 咖啡杯 - 图像过滤
- cudaimgproc - 图像处理
- cudalegacy - 遗产支持
- cudaoptflow - 光流
- cudastereo - 立体匹配
- 可口可乐 - 图像扭曲
- cudev - 设备层
gpu命名空间已被删除,使用cv :: cuda命名空间。许多课程也已经重新命名,例如:
- gpu::FAST_GPU- > cv :: cuda :: FastFeatureDetector
- gpu::createBoxFilter_GPU- > cv :: cuda :: createBoxFilter
文件格式
文档已转换为Doxygen格式。您可以在OpenCV参考文档(OpenCV的写作文档)的教程部分找到更新的文档写作指南。
支持两个版本
在某些情况下,可以支持两种版本的OpenCV。
源代码
要检查应用程序源代码中的库主要版本,应使用以下方法:
#include "opencv2/core/version.hpp"
#if CV_MAJOR_VERSION == 2
// do opencv 2 code
#elif CV_MAJOR_VERSION == 3
// do opencv 3 code
#endif
- 注意不要使用CV_VERSION_MAJOR,它对2.4和3.x分支有不同的含义!
构建系统
通过检查构建系统中的库版本,可以链接不同的模块或启用/禁用应用程序中的某些功能。可以使用标准cmake或pkg-config变量:
- OpenCV_VERSION 对于cmake将包含完整版本:“2.4.11”或“3.0.0”
- OpenCV_VERSION_MAJOR 对于cmake将仅包含主版本号:2或3
- pkg-config文件有标准字段 Version
例:
if(OpenCV_VERSION VERSION_LESS "3.0")
# use 2.4 modules
else()
# use 3.x modules
endif()