[关闭]
@nrailgun 2016-11-11T18:10:31.000000Z 字数 1788 阅读 2519

OpenCV C++ 核心接口简览

程序设计


大四时候选修了图形学的课程,然而当时正沉迷于电子游戏,没有认真学习,程序写得乱七八糟,OpenCV 也没有认真看。这两天正好有空,赶紧补习。

图像基本容器结构

Mat 是 OpenCV 的基本图像容器,本质是矩阵。构造函数定义如下:

  1. C++: Mat::Mat();
  2. C++: Mat::Mat(int rows, int cols, int type);
  3. C++: Mat::Mat(Size size, int type);

一般通过 imread 方法读入图像:

  1. cv::Mat imread(const char *filename, int imgtype);

例子:

  1. Mat A, B;
  2. A = imread(argv[1], CV_LOAD_IMAGE_GRAYSCALE);
  3. B = A.clone();

容器数据类型

容器数据类型通过 CV_MAKE_TYPE(depth, channel) 来定义。channel 是指矩阵 channel 数量(举例,对于 RGB 图像,channel 为 3)。depth 是指数据类型长度,宏定义如下:

type size cvtype
unsigned 1 CV_8U
unsigned 2 CV_16U
unsigned 4 CV_32U
signed 1 CV_8S
signed 2 CV_16S
signed 4 CV_32S
float 4 CV_32f
float 8 CV_64f

例如,构造一个 的浮点矩阵:

  1. Mat M(2, 2, CV_MAKE_TYPE(CV_32F, 3));

OpenCV 为常用类型提供了宏定义,形式为 CV_${NBIT}${TYPE}${CHN}。比如,定义 的浮点为 CV_32F3

容器数据类型转换

通过 convertTo 方法实现数据类型转换:

  1. void convertTo(OutputArray m, int rtype, double alpha=?, double beta=?);

这很重要,因为可以通过转换数据类型来适配某些不能适用于当前数据类型的操作或者函数。

矩阵遍历与索引

C-style

这是我最喜欢的粗暴直接的方法。OpenCV 提供了 atptr 方法用于直接访问 Mat 内部数据结构:

  1. Mat I;
  2. I.at<uchar>(0, 0) = 0;
  3. for(int i = 0; i < I.rows; ++i) {
  4. uchar *p = I.ptr<uchar>(i);
  5. for (int j = 0; j < I.cols; ++j) {
  6. p[j] = rand() % 256;
  7. }
  8. }

Iterator

OpenCV 提供了模板方法 beginend 来实现类似 STL 的迭代器:

  1. MatIterator_<Vec3b> it;
  2. for(it = I.begin<Vec3b>(); it != I.end<Vec3b>(); ++it) {
  3. (*it)[0] = 2;
  4. (*it)[1] = 1;
  5. (*it)[2] = 0;
  6. }

2D 滤波器

OpenCV 提供了 2D 滤波操作 filter2D,所以只要实现核函数就可以了。

  1. void filter2D(InputArray src, OutputArray dst, int ddepth, InputArray kernel,
  2. Point anchor=?, double delta=?, int borderType=?) ;

一个拉普拉斯算子的例子:

  1. Mat kern = (Mat_<char>(3, 3) << 0, -1, 0, -1, 5, -1, 0, -1, 0);
  2. Mat oimg;
  3. filter2D(cvimg, oimg, cvimg.depth(), kern);

使用技巧

转换 raw data 到 Mat

  1. cv::Mat cvimg(cv::Size(w, h), CV_32FC1, (void *) data, cv::Mat::AUTO_STEP);
  2. cv::imshow("", cvimg);
  3. cv::waitKey(0);

截取区域

注意:并不是 clone

  1. J = I(Rect(x, y, w, h));

初始值

  1. Mat C = (Mat_<double>(3,3) << 0, -1, 0, -1, 5, -1, 0, -1, 0);

To boolean

  1. cv::Mat m;
  2. m = (m != 0);
  3. m = cv::min(m, 1);

Resize without smoothing

  1. resize(I, I, Size(w, h), alpha, beta, CV_INTER_NN);

BGR 2 GRAY

  1. cv::cvtColor(im, rv, CV_BGR2GRAY);
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注