opencv 笔记


基础数据结构


简单的基础数据类型定义

opencv在对一些跟图像特征相关的基础的数据类型宏定义规则上有一定的规律,例如:CV_8UC1, CV_16SC1, CV_64FC4, …。

8U表示8位无符号整数。

16S表示16位有符号整数。

64F表示64位浮点数

C后面的数字表示通道数。例如: C1表示一个通道,C4表示4个通道。

也即:

1
CV_[位数][带符号与否][类型前缀]C[通道数]

更多的数据类型宏定义在opencv2/core/hal/interface.h中。


Mat类

新版本的opencv开始引入Mat类来表示图像。与之前的C版本的IplImage和CvMat数据结构相比,Mat类能够自动管理内存,使用者不需要花费大量精力 在内存管理上。

1.Mat类有两个数据部分组成: 矩阵头(包含矩阵尺寸,存储方法,存储地址等信息),和一个指向存储所有像素值的矩阵指针。

2.许多Mat方法通常不进行内存的复制操作。如果将局部区域赋值给新的Mat对象,新对象与原始对象 共用相同的数据区域。不申请内存。这在计算量很大的图像处理时,可加快程序执行速度。

3.Mat类使用引用计数来管理内存

4.赋值运算符和拷贝构造函数只复制信息头

5.某些情况下可用clone()或者copyTo()来复制图像矩阵

  • 迭代器: MatIterator_<T>
    Mat src = imread(FILE_NAME);
    Mat range = src(Range::all(), Range(1, 30));

    MatIterator_<Vec3b> iter = range.begin<Vec3b>();
    for(; iter != range.end<Vec3b>(); iter++){
        (*iter)[0] = 0; // B
        (*iter)[1] = 0; // G
        (*iter)[2] = rand() % 255; // R
    }
  
  
  • 选取图像局部区域

    1.单行单列

Mat类提供了多种方便的方法来选择图像的局部区域。

  Mat Mat::row(int i) const
  Mat Mat::col(int j) const

  Mat line = A.row(i);

  

2.多行多列

Range对象可用来表示矩阵的多个连续行或多个连续的列。范围为[start~end)

Range类还提供一个静态方法all()

  /* 创建一个单位矩阵 */
  Mat A = Mat::eye(10, 10, CV_32S);

  /* 提取1-3列,但不包含第3列 */
  Mat B = A(Range::all(), Range(1, 3));

  /* 提取B的第5—9行(不包含9) */
  Mat c = B(Range(5, 9), Range::all());

  

3.区域 ROI

  Mat img(Size(320, 240), CV_8UC3);

  /* 利用mat构造函数选取区域 */
  Mat r1(img, Rect(10, 10, 100, 100));

  /* 利用Mat operator() (const& Rect) const 构造*/
  Mat r2 = img(Rect(10, 10, 100, 100));

  /* 利用operate() (Range, Range) const 构造 */
  Mat r3 = img(Range(10, 100), Range(10, 100));