OpenCV 数据结构
矩阵类
Mat
创建矩阵
- 行列方式:指明矩阵的维度和数据类型,并且赋值为常数。
- 拷贝创建方式:从其它矩阵拷贝、切片过来。可以利用
Rect
(获取 ROI)、Range
(在不同维度上切片)、void* data
(给定数据的地址)得到。 - 从
vector
、array
得到
数据类型
CV_[bit](U|S|F)C[channels]: U——无符号数;S——有符号整形;F——浮点数。
属性
- depth:每一个像素的精度,与 bit 数有关,与图像通道数无关。
这个可以在图像滤波中用到,函数中传入参数
ddepth
就指明输出矩阵的精度。
- step:矩阵中每一行的字节数 / step1 :每一通道的字节数。
用作指针遍历矩阵时,跨行索引的标准。
操作
- 行、列切片:
rowRange
\colRange
- 矩阵拼接:
push_back
- 矩阵变形:
reshape
\resize
- 类型转换:
convertTo
- 重新分配空间:
create
相当于重新声明一个新的大小和类型的矩阵,预先分配空间。 - 区域选择(ROI):一是在定义
Mat
变量时;二是用iamge(Range(), Range())
。 - 赋统一数值:
setTo
- 提取
ROI
:参考()
运算符 ,支持Rect
类索引和Range
类(行列范围)。
矩阵创建
- 创建一定维数的空矩阵
- 采用
void* data
浅拷贝创建矩阵 - 采用
Rect
选取Mat
内ROI
(见Mat
构造函数) - 采用
<<
创建
第四种方法如下所示:
Mat a = (Mat_<double>(3, 3) << 0, 1, 2, 3, 4, 5, 6, 7, 8);
本质上是先使用
MatCommaInitializer_<T>& operator,(T2 v);
创建MatCommaInitializer_<T>
再重载,
运算符MatCommaInitializer_<T>& operator,(T2 v);
之后用这个来初始化Mat
访问元素
at
访问: 访问时需要指定类型。矩阵类型与 C 类型对应[关系](OpenCV: cv::Mat Class Reference) 。通道数与Vec
的维数相同。
image.at<uchar>(j, i) = 255; // CV_8UC1 Image
image.at<Vec3b>(j, i)[0] = 255; // CV_8UC3 Image
image.at<Vec3b>(j, i)[1] = 255;
image.at<Vec3b>(j, i)[2] = 255;
at
需要指定类型原因在于编译时,不知道矩阵的实际类型。如果用 Mat_
类实际指明,则不需要额外指明类型。
cv::Mat_<uchar> im2(image);
im2(j, i) = 255;
- 指针访问
uchar* data = image.ptr<uchar>(j); // acquire thr row j address
for(int i = 0; i < image.cols; i++)
data[i] = ... // offset col j,
data = image.data + j * image.step + i * image.elemSize(); // j row & i col offset
如果当矩阵数据在内存空间中是连续的(Mat::isContinuous()
函数返回 True)可以将矩阵看成一个一维的数组,直接用指针偏移访问。
InputArray
InputArray
类可以由 Mat
, Mat_<T>
, Matx<T, m, n>
, std::vector<T>
, std::vector<std::vector<T> >
, std::vector<Mat>
, std::vector<Mat_<T>>
, UMat
, std::vector<UMat>
或者 double
创建。也可以传入 GPU 矩阵。
- 传入空矩阵可以用
cv::noArray()
或者cv::Mat()
。- 这个类仅是用来传递参数,不应该在实际运算中使用。
使用
使用 kind()
或者 is*()
方法判断传入具体参数类型;使用 get*()
获取具体的数据。
Iterative Algorithm
TermCriteria
类
TermCriteria
类确定了迭代算法终止条件。终止条件分为两种:
- 迭代次数(MaxCount)
- 精度(Eps)
从其构造函数可以看出:传入两个参数 maxCount
和 epsilon
确定终止条件,type
则是选择终止条件。可以选择 cv::TermCriteria::Type::MAX_CPUNT
和 cv::TermCriteria::Type::EPS
。(同时选择是或操作)
从具体解析来看,会将 type
标志位比较,如果选中,则读取输入值,否则选择默认值。
if( !(termcrit.type & CV_TERMCRIT_ITER) )
termcrit.maxCount = 5;
termcrit.maxCount = MAX(termcrit.maxCount,1);
termcrit.maxCount = MIN(termcrit.maxCount,100);
if( !(termcrit.type & CV_TERMCRIT_EPS) )
termcrit.epsilon = 1.f;
termcrit.epsilon = MAX(termcrit.epsilon, 0.f);