您的位置:首页 > 运维架构

和OpenCV1的互通性

2016-03-06 11:15 330 查看
目标:

对于OpenCV的开发团队来说持续地完善这个库是非常重要的。我们一直都致力于向办法去让你的工作过程变得简单容易,与此同时保持这个库的灵活性。新的C++界面就是我们对这个目标的一个发展。然而,向前兼容却是非常重要的。我们不想因为早起的OpenCV库版本而中断你的代码工作。因此,我们确保通过添加一些函数来处理这个问题。在接下来的介绍中你将了解:

相对于OpenCV的第一版,其第二版在你使用的方式上有什么改变;

怎么样为一幅图像加入高斯噪音;

什么是查询表以及我们为什么要使用它?

概述:

在转换的过程中你首先需要知道一些图像的基本数据结构:Mat。它替换了旧版的CvMat和IplImage。转换到新的函数是很容易的,你只需要记住一些新的东西就可以了。

OpenCV2接受重组,所有的函数不再仅仅放到一个库里面。我们有许多模块,它们中的每一个都包含数据结构和与特定任务相关的函数。这样的话当你只使用OpenCV的一个子集的时候就不需要把整个库都加载进去。这就意味着你仅仅只需要包含你所使用的这些头文件就可以了。

所有和OpenCV相关的东西都被放到CV的命名空间,以此来避免和其他库的数据结构和函数的命名冲突。因此,在开始OpenCV的所有工作之前或者在include之后,你需要预先将CV::Keywords声明一下,或者只需要添加一个预编译指令即可:

Usingnamespace CV;

因为所有函数都已经在命名空间中了,因此就没必要给这些函数再加上CV的前缀了。所有新的C++兼容函数都没有这个前缀,并且都遵守这个命名规则。这就意味着首字母都是小写的(除非是一个名字,例如Canny)并且随后的单词以大写字母开头(就像copyMakeBorder).

现在,记住你需要将所有你使用的模块链接到你的应用中,如果你是在Windows下使用DLL系统,你将需要再一次将所有文件的路径添加进去。更深入的可以参考官网上的教程。

现在为了转换Mat对象,你可以使用早期的IplImage或者CvMat操作。在C环境下就使用指针就可以了。在C++环境下最多的是使用Mat对象。这些对象都可以通过简单地赋值很方便地转换成IplImage和CvMat。例如:

MatI;

IplImagepI=I;

CvMatmI=I;

现在如果你想要得到指针,这个转换就变得有点复杂了。编译器不再能够自动确定你想要什么,所以你需要明确你的目标。这就需要调用IplImage和CvMat操作符然后得到他们的指针,为了得到指针我们可以使用&符号:

MatI;

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

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

C环境的一个最大的麻烦就是它将所有的内存管理交给你自己去处理。你需要明确什么时候去释放你不使用的对象是安全的并且确保在程序完成之前你这样做不会有内存泄漏的麻烦。为了解决这个问题,在OpenCV中引入了一个智能指针类。当你不使用的时候这个可以自动释放对象。去使用这个声明这种指针需要专门用到Ptr:

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

将上述的piI作为参数传递给其构造函数就完成了从C数据结构到Mat的转换。

Mat K(piI),L;

L=Mat(pI);

/*************************************************
**			Translator:York.
**			Email:y_zhou1991@163.com
**			Date:2016/03/06
**************************************************/

#include<cv.h>
#include<highgui.h>
#include<imgproc\imgproc.hpp>

using namespace cv;
using namespace std;

//#define DEMO_MIXED_API_USE

int main(int argc, char** argv)
{
const char* imagename = "F:/Photo/OpenCV_Photo/fruits.jpg";

//#ifdef DEMO_MIXED_API_USE
Ptr<IplImage> IplI = cvLoadImage(imagename);
if (IplI.empty())
{
cerr << "Can not load image " << imagename << endl;
return -1;
}
Mat I(IplI);//转换成新的类型容器,但是只有头文件被创建了,图像没有拷贝
cerr<<"Image has been loaded!"<<endl;
imshow("My",I);
//waitKey();
//#else
/*Mat I=imread(imagename);
if(I.empty())
{
cerr << "Can not load iamge " << imagename << endl;
return -1;
}*/

//#endif

Mat I_YUV;
cvtColor(I, I_YUV, COLOR_BGR2YCrCb);

vector<Mat> planes;
split(I_YUV, planes);
//显示各通道的图像
/*imshow("out1", planes[0]);
imshow("out2", planes[1]);
imshow("out3", planes[2]);
waitKey();*/
// Method 1. process Y plane using an iterator
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_cast<uchar>(v*v / 255);
}
imshow("out1", planes[0]);
for (int y = 0; y < I_YUV.rows; y++)
{
// Method 2. process the first chroma plane using pre-stored row pointer.
uchar* Uptr = planes[1].ptr<uchar>(y);
for (int x = 0; x < I_YUV.cols; x++)
{
Uptr[x] = saturate_cast<uchar>((Uptr[x] - 128) / 2 + 128);

// Method 3. process the second chroma plane using individual element access
uchar& Vxy = planes[2].at<uchar>(y, x);
Vxy = saturate_cast<uchar>((Vxy - 128) / 2 + 128);
}
}
/*imshow("out1", planes[0]);
imshow("out2", planes[1]);
imshow("out3", planes[2]);
waitKey();*/
/*imshow("out2", planes[1]);
imshow("out3", planes[2]);*/

Mat noisyI(I.size(), CV_8U);
/*imshow("noisy", noisyI);
waitKey();*/
//高斯分布的随机数矩阵;第二个参数是均值,第三个参数是标差。
randn(noisyI, Scalar::all(128), Scalar::all(0));
imshow("noisy", noisyI);
//对图像进行高斯滤波
GaussianBlur(noisyI, noisyI, Size(3, 3), 0.5,0.5);
imshow("noisy1", noisyI);
const double brightness_gain = 0;
const double contrast_gain = 1.7;

//#ifdef DEMO_MIXED_API_USE
//	// To pass the new matrices to the functions that only work with IplImage or CvMat do:
//	// step 1) Convert the headers (tip: data will not be copied).
//	// step 2) call the function   (tip: to pass a pointer do not forget unary "&" to form pointers)
//
//	IplImage cv_planes_0 = planes[0], cv_noise = noisyI;
//	cvAddWeighted(&cv_planes_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
imshow("out7", planes[0]);

const double color_scale = 0.5;
// Mat::convertTo() replaces cvConvertScale.
// One must explicitly specify the output matrix type (we keep it intact - planes[1].type())
planes[1].convertTo(planes[1], planes[1].type(), color_scale, 128 * (1 - color_scale));
imshow("out8", planes[1]);
// alternative form of cv::convertScale if we know the datatype at compile time ("uchar" here).
// This expression will not create any temporary arrays ( so should be almost as fast as above)
planes[2] = Mat_<uchar>(planes[2] * color_scale + 128 * (1 - color_scale));
imshow("out9", planes[2]);
// Mat::mul replaces cvMul(). Again, no temporary arrays are created in case of simple expressions.
planes[0] = planes[0].mul(planes[0], 1. / 255);

merge(planes, I_YUV);  // now merge the results back
imshow("out10", I_YUV);
cvtColor(I_YUV, I, CV_YCrCb2BGR);  // and produce the output RGB image
namedWindow("image with grain", WINDOW_AUTOSIZE);   // use this to create images

//#ifdef DEMO_MIXED_API_USE
//	// this is to demonstrate that I and IplI really share the data - the result of the above
//	// processing is stored in I and thus in IplI too.
//	cvShowImage("image with grain", IplI);
//#else
imshow("image with grain", I); // the new MATLAB style function show

//#endif

waitKey();
//system("pause");
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: