一:Opencv2与opencv1的区别:
Opencv1.0版本于2006年面世,主要基于C语言。2009年发布opencv2,主要基于C++。此时opencv库被划分成多个模块,这些模块被编译成库文件后,位于lib文件夹中。主要有以下模块(版本1的结构见我的这篇blog:http://blog.csdn.net/lu597203933/article/details/13614377):
Opencv_core模块:包含核心功能,尤其是底层数据结构和算法函数。
Opencv_improc模块:包含图像处理函数。
Opencv_highgui模块:包含读写图像及视频的函数,以及操作图形用户界面函数。
Opencv_features2d模块:包含兴趣点检测子,描述子以及兴趣点匹配框架。
Opencv_calib3d模块:包含相机标定,双目几何估计以及立体视觉函数。
Opencv_video模块:包含运动估算,特征跟踪以及前景提取函数与类。
Opencv_objdetect模块:包括物体检测函数,如脸部和行人检测。
库中还包含其它的工具模块,如机器学习(opencv_ml),计算几何(opencv_flann),第三方代码(opencv_contrib)等。这些模块都对有一个单独的头文件(位于include文件夹)。推荐的声明方式如下:
#include<opencv2\core\core.hpp>
#include<opencv2\highgui\highgui.hpp>
#include<opencv2\imgproc\imgproc.hpp>
而#include "cv.h"这是旧的代码方式,那是库还没有被划分为模块。
二:读取、显示和保存图片
(1)代码:
[cpp] view plain copy print ?
- #include <opencv2\core\core.hpp>
- #include <opencv2\highgui\highgui.hpp>
- #include <opencv2\imgproc\imgproc.hpp>
- #include <iostream>
- using namespace std;
- using namespace cv;
- int main()
- {
- Mat image = imread("F:\\tongtong.jpg", 1); //读取图片
- if(!image.data) // data指向已分配内存块的指针
- {
- cout << "fail to load image" << endl;
- }
- cout << "image size: " << image.size().height << "," << image.size().width << endl; //size()返回的是一个结构体
- namedWindow("show");
- imshow("show", image); // 显示图片
- imwrite("F:\\tongtong2.jpg", image);
- <span style="white-space:pre"> </span>Mat result;
- flip(image,result, 0);
- namedWindow("result",0);
- imshow("result", result);
- waitKey(0);
- return 0;
- }
(2)Explaination:
<1>opencv2中用于存储图像数据为Mat类型,而在opencv1中用IplImage(详细见我的这篇blog:http://blog.csdn.net/lu597203933/article/details/13957271)。优点在于Mat是一个类,定义的类类型可以自动分配和释放内存空间,而IplImage需手动为其分配和释放内存空间,当图像较多时,可能会有偏差,造成内存泄露。
<2>image.data是指向已分配的内存块的指针,当图片没有加载进来,则为NULL。
<3>image.size()返回的是一个结构体,实际上包括width和height这两个成员变量。
<4>flip(image,result,0); //其中正数表示水平反转,0表示垂直反转,负数表示既有水平又有垂直反转。
(3)结果:
三:深浅拷贝
(1) 浅拷贝:
Mat B;
B = image ; // 第一种方式
Mat C(image); // 第二种方式
这两种方式称为浅copy,是由于它们有不同的矩阵头,但是它们共享内存空间,即指向一个矩阵。当图像矩阵发生变化时,两者相关联,都会变化。
(2) 深拷贝:
Mat B,C;
B = image.clone(); // 第一种方式
image.copyTo(C); // 第二种方式
深拷贝是真正的copy了一个新的图像矩阵,此时image,B,C三者相互没有影响。
四:IplImage装换为Mat
IplImage*iplImage = cvLoadImage("F:\\11.jpg",1);
Mat image2(iplImage,false);
// 其中false为浅拷贝,而true为深拷贝,默认为false。此时注意需要释放iplImage
当然opencv提供了另外一种指针类,无需手动释放,但现在已经不用了,可以使用它来封装IplImage指针:
Ptr<IplImage> iplImage = cvLoadImage("F:\\11.jpg",1);
作者:小村长 出处:http://blog.csdn.net/lu597203933 欢迎转载或分享,但请务必声明文章出处。 (新浪微博:小村长zack, 欢迎交流