OpenCV_Tutorials——CORE MODULE.THE CORE FUNCTIONALITY—— Interoperability with OpenCV 1

2.10 和OpenCV的互用性

目标

对于OpenCV的开发团队来说,不断提升OpenCV库是非常重要的。我们不断考虑那些可以减轻你工作过程的方法,同时还要保障库的灵活性。新的C++接口就是我们为了这个而开发出来的东西。然而,向后兼容性仍然是很重要的。我们不想打碎那些你使用更早的OpenCV库写下的代码。因此,我们为了保障这个事情从而加上了一些函数。在下面的教程中,你会学习到:

1、相比于同样使用的第一版本的OpenCV库,第二版本中有了什么变化。

2、如何在图像中添加一些高斯噪点。

3、什么是查找表,为什么要用他们。

概述

你做出改变的第一步就是学习关于图像的一些新的数据结构:Mat-The Basic Image Container这里代替了老旧的CvMat 和ImpImage。使用新的方程看起来更为容易一些。你只需要记住一下几件新的事情。

OpenCV 2 接受改编。不再将所有的函数都塞进单一库中。我们有许多模块,其中每一个都包括数据结构和函数相关的某些任务。通过这个方法,如果你只需要OpenCV的一部分,你就不用调用这个库。这就意味着你需要引入那些你需要的头文件。例如:

#Include<opencv2/core/core.hpp>

#include<opencv3/imgproc/imgproc.hpp>

#include<opencv2/highgui/highgui.hpp>

所有和OpenCV相关的东西都北方到了cv名字空间(namespace)中从而防止和其他库的数据结构和函数发生名字冲突。因此你需要再任何来自于OpenCV库的东西前面添加cv::关键字或者直接添加这一行代码直接包含所有:

using  namespace cv;

因为函数已经在命名空间中了,也就不需要在名字前面添加cv前缀。所有的新的可兼容函数不具有这一点,他们遵循驼峰命名法。这就意味名字的第一个字母是小写字母(除非它本身就是一个名字(人名等)像Canny)接下来的单词使用大写字母开头(像copyMakeBorder)。

现在,要记住你需要将你用的所有模块连接到你的应用程序中。在Windows环境下,你需要将使用了的DLL再次添加进所有的二进制的路径中。更多深层次的信息,如果你使用Windows,请阅读 How to build applications with OpenCV inside the Microsoft Visual Studio对于Linux的使用案例,在Using OpenCV with Eclipse(添加CDT)中有所解释。

现在,为了转换Mat 对象,你可以使用IplImage或者CvMat操作符。然而在C接口中通常使用的指针,在这里不复存在了。在C++接口中,我们更多使用Mat 对象。这种对象可以不花费任何代价只需要简单的赋值就可以转换为IplImage和CvMat类型。例如:

Mat I;

IplImager PI=I;

CvMat mI=I;

现在如果你想转换到指针的,就会有一点麻烦。编译器不再自动决定你想要什么而是你需要明确指定你的目的。也就是调用IplImage和CvMat 操作符并且得到他们的指针。为了的到指针,我们使用&标记:

Mat I;

IplImage *pI=&I,operator IplImage();

CvMat *mI= &I.opeartor CvMat();

C接口的最大的弊端就是让你自己进行内存管理。你需要知道什么时候你析构一个不再用到的内存是安全的并且确保你在程序运行完成后进行,否则你可能就会有内存泄漏的麻烦了。为了解决OpenCV中的这个问题,这里引入了一系列的智能指针。当对象不再使用时,就会被自动析构掉。使用这个被特殊声明的指针Ptr:

Ptr<IplImage> piI=&I.operator IplImage();

从C的数据结构转换到Mat 是通过将它们传入内部的构造函数完成的。例如:

Mat K(piL),L;

L=Mat(pI);

关于学习

现在你已经基本完成了混合使用C接口和C++接口的例子。你也将会在OpenCV的实例文件夹中找到源代码。为了帮助你看到两者的不同:一个是C和C++的混合,另外一个则是纯C++。如果你定义DEMO_MIXED_API_USE你就不再使用第一个。程序将色彩平面分离,然后在上面做一些改动,最后将它们融合到一起。

#include<stdio.h>

#include<iostream>

#include<opencv2/core/core.hpp>

#include<opencv2/imgproc/imgproc.hpp>

#include<opencv2/highgui/highgui.hpp>

Using namespace cv;

Using namespace std;

#define DEMO_MIXED_API_USE

int main(int argc,char**argv)

{

Const char* imagename=argc>1?argv[1]:”lena.jpg”;
}

#ifdef DEMO_MIXED_API_USE

Ptr<Iplimage> IplI=cvLoadImage(imagename);

If(IplI.empty())

{

Cerr<<”an not load image”<<imagename<<endl;

Return -1;
}

Mat I(IplI);

#else

Mat I=imread(imagename);

If(I.empty())

{

Cerr<<”can not load image”<<imagename<<endl;

Return -1;
}

#endif

在这里你能看到使用了新的结构,我们不再有指针问题,尽管使用了老旧的函数,但是最终还是将结果转换为Mat 对象

Mat I_YUV;

cvtColor(I,I_YUV,COLOR_BGR2YCrCb);

Vector<Mat> planes;

Split(I_YUV,planes);

因为我们想要将图像中的亮度成分混合,我们首先将默认RGB色彩系统转换为YUV色域然后将它分离为不同的色彩平面。这里的程序分离:在第一个示例中使用三个(C语言中的[]操作符,迭代器,读取独立元素)主要的图像遍历算法中的一个来处理每一个平面。第二个变化就是我们在图像中加入高斯噪声并且根据某些方程将它们的通道融合。

MatIterator_<uchar> it=planes[0].begin<uchar>(),it_end=planes[0].end<uchar>();

For(;it!=it_end;++it)

{

Double v=*it*1.7+rand()%21-10;

*it=saturate_case<uchar>(v*v/255);
}

For(int y=0;y<I_YUV.rows;y++)

{

Uchar* Uptr=planes[1].ptr<ujchar>(y);

For(int x=0;x<I_YUV.cols;x++)

{

Uptr[x]=saturate_cast<uchar>((Uptr[x]-128/2)+128);

Uchar&Vxy=planes[2].at<uchar>(y,x);

Vxy=saturate_cast<uchar>((Vxy-128)/2+128);
}
}

在这里你能够看到我们通过三种方式(迭代器,C指针以及独立元素进入方式)来遍历整个图像中的像素。你可以从How to scan images,lookup tables and time measurement with OpenCV教程来获得更多的深层次的描述。很容易转换老旧的函数名称。仅仅把cv前缀去掉然后使用新的Mat 数据结构。下面就是通过使用增加权重的函数的使用案例:

Mat noisyI(I.size(),.CV_8U);

Randn(noisyI,Scalar::all(128),Scalar::all(20));

GaussianBlur(noisyI,noisyI,Size(3,3),0.5,0.5);

Const double brightness_gain=0;

Const double contrast_gain=1.7;

#ifdef  DEMO_MIXED_API_USE

IplImage cv_planes_0=planes[0],cv_noise=noisyI;

cvAddWeighted(&cv_lanes_0,contrast_gain,&cv_noise,1,-128+brightness_gain,&cv_planes_0);

#else

addWeighted(planes[0],contrast_gain,noisyI,1,-128+brightness_gain,planes[0]);

#endif

Const double color_scale=0.5;

Planes[1].convertTo(planes[1],planes[1].type(),color_scale,128*(1-color_scale));

Planes[2]=Mat_<uchar>(planes[2]*color_scale+128*(1-color_scale));

Planes[0]=planes[0].mul(planes[0],1./255);

你可能看到平面变量的类型是Mat。然而从Mat 转换到IplImage容易而且使用一个赋值操作就可以自动完成。

Merge(planes,I_YUV);

cvColor(I_YUV,I,CV_YCrCb2BGR);

namedWindow(“image with grain”,WINDOW_AUTOSIZE);

#ifdef DEMO_MIXED_API_USE

cvShowImage(“image with grain”.IplI);

#else

Imshow(“image with grain”,I);

新的imshow highgui函数接受Mat和IplImage两种数据结构。编译和运行程序,如果下面第一幅图像是你的输入图像,你可能的到第二章或者第三章图像作为输出。

时间: 2024-12-19 08:08:38

OpenCV_Tutorials——CORE MODULE.THE CORE FUNCTIONALITY—— Interoperability with OpenCV 1的相关文章

OpenCV_Tutorials——CORE MODULE.THE CORE FUNCTIONALITY—— File Input and Output using XML and YAML files

2.9XML和YAML格式作为文件输入输出 目标 你会从文中找到下面问题的答案: 1.如何从OpenCV使用的YAML或者XML文件中读取和打印文字条目.? 2.对于OpenCV数据结构如何做到相同的事情? 3.对你的数据结构如何做到? 4.OpenCV的数据结构,例如FileStorage,FileNode或者FileNodeIterator的使用方法. 源代码 你可以从这里下载代码或者从OpenCV的源代码库的samples/cpp/tutorial_code/core/file_input

OpenCV_Tutorials——CORE MODULE.THE CORE FUNCTIONALITY——Random genenrator and text with OpenCV

2.7 随机产生器和OpenCV当中的文字 目标 在教程中,你会学习到: 1.使用随机数字产生类(RNG)并且如何从均匀分布中获得随机数字. 2.使用OpenCV的putText函数在窗口中显示文字 代码 1.在前一个的教程(Basic Drawing)中,我们画了不同的几何图形,给出了例如坐标(使用Points形式的)的输入参数,颜色,线条粗细,等等.你可能已经注意到我们对于那些参数都是给出了特殊的值. 2.在本教程中,我们打算使用为绘图参数使用随机值.同样,我们打算使用大量的几何图形来填满我

OpenCV_Tutorials——CORE MODULE.THE CORE FUNCTIONALITY—— Discrete Fourier Transform

2.8 离散的傅立叶变换 目标 我们要寻找以下问题的答案: 1.什么是傅立叶变换,为什么我们要用这个? 2.在OpenCV中如何做到? 3.例如copyMakeBorder(),merge(),dft(),getOptimalDFGSize(),log()以及normalize()函数的用法. 源代码 你可以从这里下载或者从samples/cpp/tutorial_code/core/discrete_fourier_transform/discrete找到代码. #include "openc

OpenCV_Tutorials——CORE MODULE.THE CORE FUNCTIONALITY—— Adding(blending) two images using OpenCV

2.5 改变图像的对比度和明暗 目标 在教程中,你会学到如何: 1.读取像素值 2.用0初始化一个矩阵 3.学习staurate_cast是做什么的 4.获取有关像素变换的一些更酷的信息(Get some cool info about pixel transformations) 理论 注意,下面的解释来自于Richard Szeliski所写的<Computer Vision:Algorithms and Applications> 图像处理 1.一般的图像处理机是一个接受一个或多个输入图

OpenCV_Tutorials——CORE MODULE.THE CORE FUNCTIONALITY——Adding (blending) two images using OpenCV

目标 在教程中你会学到: 1.什么事线性混合,它有什么用. 2.如何使用addWeighted将两个图像相加 理论 注意:下面的解释来自Richard Szeliski写的<Computer Vision:Algorithms and Application>. 在前面的教程中,我们已经学习了一些像素的运算.一个有意思的二元(两个输入)运算符就是线性混合运算符: 通过α从0到1变化这个运算符可以被用做两个图像或者录像之间的时间交融(cross-dissolve,这里tutorial里面用的是c

OpenCV_Tutorials——CORE MODULE.THE CORE FUNCTIONALITY—— Mat - The Basic Image Container

在家这段时间内,发现了这样的OpenCV库自带的教程,感觉不错,尝试翻译并且添加一些tips,帮助自己学习,同时也与各位交流一下. 核心模块.核心功能 这里这两部分说的是核心模块以及核心功能的简介,其中蓝字部分可以链接到相关部分,这里我采用顺序方法,从第一部分,即 “Mat:The Basic Image Container”开始叙述. 2.1 基本的图像容器—矩阵 目标 我们可以通过许多途径从真实世界获取数字图像,例如:数码相机.扫描仪.计算机断层扫描以及磁成像共振等等.不管怎样,那些都只是我

Nginx - Core Module Directives

The following is the list of directives made available by the Core module. Most of these directives must be placed at the root of the configuration file and can only be used once. However, some of them are valid in multiple contexts. If that is the c

AngularJS------Error: Cannot find module &#39;@angular-devkit/core&#39;

如图: 解决方法: 进入项目目录下执行以下代码 npm i --save-dev @angular-devkit/core AngularJS------Error: Cannot find module '@angular-devkit/core' 原文地址:https://www.cnblogs.com/tianhengblogs/p/8452045.html

2.Nginx学习-The HTTP Core module

http core module是Ngnix提供WEB服务的最核心模块,默认被开启.本篇文章将讲述该模块的一些配置 配置文件结构: http {     server {// virtual website         location{         }     }     server{       location{       }     } } 原文地址:http://blog.51cto.com/xwandrew/2087751