天天看点

Opencv2系列学习笔记1(图像的基本操作)

一: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 ?

  1. #include <opencv2\core\core.hpp>  
  2. #include <opencv2\highgui\highgui.hpp>  
  3. #include <opencv2\imgproc\imgproc.hpp>  
  4. #include <iostream>  
  5. using namespace std;  
  6. using namespace cv;  
  7. int main()  
  8. {  
  9.     Mat image = imread("F:\\tongtong.jpg", 1);  //读取图片  
  10.     if(!image.data)                  // data指向已分配内存块的指针  
  11.     {  
  12.         cout << "fail to load image" << endl;  
  13.     }  
  14.     cout << "image size: " << image.size().height << "," << image.size().width << endl; //size()返回的是一个结构体  
  15.     namedWindow("show");  
  16.     imshow("show", image);       // 显示图片  
  17.     imwrite("F:\\tongtong2.jpg", image);  
  18. <span style="white-space:pre">  </span>Mat result;  
  19.     flip(image,result, 0);  
  20.     namedWindow("result",0);  
  21.     imshow("result", result);  
  22.     waitKey(0);  
  23.     return 0;     
  24. }  

    (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)结果:

Opencv2系列学习笔记1(图像的基本操作)

三:深浅拷贝

(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, 欢迎交流

继续阅读