.. _InteroperabilityWithOpenCV1: 与 OpenCV 1 同时使用 ****************************** 目的 ==== 对于OpenCV的开发团队来说,持续稳定地提高代码库非常重要。我们一直在思考如何在使其易用的同时保持灵活性。新的C++接口即为此而来。尽管如此,向下兼容仍然十分重要。我们并不想打断你基于早期OpenCV库的开发。因此,我们添加了一些函数来处理这种情况。在以下内容中你将学到: .. container:: enumeratevisibleitemswithsquare + 相比第一个版本,第二版的OpenCV在用法上有何改变 + 如何在一幅图像中加入高斯噪声 + 什么事查找表及如何使用 概述 ======= 在用新版本之前,你首先需要学习一些新的图像数据结构: :ref:`matTheBasicImageContainer` ,它取代了旧的 *CvMat* 和 *IplImage* 。转换到新函数非常容易,你仅需记住几条新的原则。 OpenCV 2 接受按需定制。所有函数不再装入一个单一的库中。我们会提供许多模块,每个模块都包含了与其功能相关的数据结构和函数。这样一来,如果你仅仅需要使用OpenCV的一部分功能,你就不需要把整个巨大的OpenCV库都装入你的程序中。使用时,你仅需要包含用到的头文件,比如: .. code-block:: cpp #include #include #include 所有OpenCV用到的东西都被放入名字空间 *cv* 中以避免与其他库的数据结构和函数名称的命名冲突。因此,在使用OpenCV库中的任何定义和函数时,你必须在名称之前冠以 *cv::* ,或者在包含头文件后,加上以下指令: .. code-block:: cpp using namespace cv; // 新的C++接口API都在此名字空间中,需要导入。 因为所有库中函数都已在此名字空间中,所以无需加 *cv* 作为前缀。据此所有新的C++兼容函数都无此前缀,并且遵循驼峰命名准则。也就是第一个字母为小写(除非是单个单词作为函数名,如 Canny)并且后续单词首字母大写(如 *copyMakeBorder* ). 接下来,请记住你需要将所有用到的模块链接到你的程序中。如果你在Windows下开发且用到了 *动态链接库(DLL)* ,你还需要将OpenCV对应动态链接库的路径加入程序执行路径中。关于Windows下开发的更多信息请阅读 :ref:`Windows_Visual_Studio_How_To` ;对于Linux用户,可参考 :ref:`Linux_Eclipse_Usage` 中的实例及说明。 你可以使用 *IplImage* 或 *CvMat* 操作符来转换 *Mat* 对象。在C接口中,你习惯于使用指针,但此处将不再需要。在C++接口中,我们大多数情况下都是用 *Mat* 对象。此对象可通过简单的赋值操作转换为 *IplImage* 和 *CvMat* 。示例如下: .. code-block:: cpp Mat I; IplImage pI = I; CvMat mI = I; 现在,如果你想获取指针,转换就变得麻烦一点。编译器将不能自动识别你的意图,所以你需要明确指出你的目的。可以通过调用 *IplImage* 和 *CvMat* 操作符来获取他们的指针。我们可以用 & 符号获取其指针如下: .. code-block:: cpp Mat I; IplImage* pI = &I.operator IplImage(); CvMat* mI = &I.operator CvMat(); 来自C接口最大的抱怨是它将所有内存管理工作交给你来做。你需要知道何时可以安全释放不再使用的对象,并且确定在程序结束之前释放它,否则就会造成讨厌的内存泄露。为了绕开这一问题,OpenCV引进了一种智能指针。它将自动释放不再使用的对象。使用时,指针将被声明为 *Ptr* 模板的特化: .. code-block:: cpp Ptr piI = &I.operator IplImage(); 将C接口的数据结构转换为 *Mat* 时,可将其作为构造函数的参数传入,例如: .. code-block:: cpp Mat K(piL), L; L = Mat(pI); 实例学习 ============ 现在,你已经学习了最基本的知识。 :download:`这里 <../../../../samples/cpp/tutorial_code/core/interoperability_with_OpenCV_1/interoperability_with_OpenCV_1.cpp>` 你将会看到一个混合使用C接口和C++接口的例子。你也可以在可以再OpenCV的代码库中的sample目录中找到此文件 :file:`samples/cpp/tutorial_code/core/interoperability_with_OpenCV_1/interoperability_with_OpenCV_1.cpp` 。为了进一步帮助你认清其中区别,程序支持两种模式:C和C++混合,以及纯C++。如果你宏定义了 *DEMO_MIXED_API_USE* ,程序将按第一种模式编译。程序的功能是划分颜色平面,对其进行改动并最终将其重新合并。 .. literalinclude:: ../../../../samples/cpp/tutorial_code/core/interoperability_with_OpenCV_1/interoperability_with_OpenCV_1.cpp :language: cpp :linenos: :tab-width: 4 :lines: 1-9, 22-25, 27-44 在此,你可一看到新的结构再无指针问题,哪怕使用旧的函数,并在最后结束时将结果转换为 *Mat* 对象。 .. literalinclude:: ../../../../samples/cpp/tutorial_code/core/interoperability_with_OpenCV_1/interoperability_with_OpenCV_1.cpp :language: cpp :linenos: :tab-width: 4 :lines: 46-51 因为我们打算搞乱图像的亮度通道,所以首先将图像由默认的RGB颜色空间转为YUV颜色空间,然后将其划分为独立颜色平面(Y,U,V)。第一个例子中,我们对每一个平面用OpenCV中三个主要图像扫描算法(C []操作符,迭代,单独元素访问)中的一个进行处理。在第二个例子中,我们给图像添加一些高斯噪声,然后依据一些准则融合所有通道。 运用扫描算法的代码如下: .. literalinclude:: ../../../../samples/cpp/tutorial_code/core/interoperability_with_OpenCV_1/interoperability_with_OpenCV_1.cpp :language: cpp :linenos: :tab-width: 4 :lines: 55-75 此处可看到,我们可以以三种方式遍历图像的所有像素:迭代器,C指针和单独元素访问方式你可在 :ref:`howToScanImagesOpenCV` 中获得更深入的了解。从旧的函数名转换新版本非常容易,仅需要删除 cv 前缀,并且使用 *Mat* 数据结构。下面的例子中使用了加权加法: .. literalinclude:: ../../../../samples/cpp/tutorial_code/core/interoperability_with_OpenCV_1/interoperability_with_OpenCV_1.cpp :language: cpp :linenos: :tab-width: 4 :lines: 79-112 正如你所见,变量 *planes* 也是 *Mat* 类型的。无论如何,将 *Mat* 转换为 *IplImage* 都可通过简单的赋值操作符自动实现。 .. literalinclude:: ../../../../samples/cpp/tutorial_code/core/interoperability_with_OpenCV_1/interoperability_with_OpenCV_1.cpp :language: cpp :linenos: :tab-width: 4 :lines: 115-127 新的 *imshow* highgui函数可接受 *Mat* 和 *IplImage* 数据结构。 编译并运行例程,如果输入以下第一幅图像,程序将输出以下第二幅或者第三幅图像。 .. image:: images/outputInteropOpenCV1.jpg :alt: The output of the sample :align: center 你可以在点击此处看到动态示例: `YouTube here `_ ,并可以 :download:`点击此处 <../../../../samples/cpp/tutorial_code/core/interoperability_with_OpenCV_1/interoperability_with_OpenCV_1.cpp>` 下载源文件,或者在OpenCV源代码库中找到源文件: :file:`samples/cpp/tutorial_code/core/interoperability_with_OpenCV_1/interoperability_with_OpenCV_1.cpp` 。 .. raw:: html
翻译者 ================= lurvhua@ `OpenCV中文网站 `_