前言
本文将介绍 OpenCV 中的矩阵结构 CvMat 并提供几个很常用的矩阵使用方法。
更多的矩阵处理函数还请参阅相关资料。
CvMat 的类型定义
1 typedef struct CvMat
2 {
3 int type; // 数据类型
4 int step; // 行长度
5 int* refcount; /* 内部使用 */
6 int hdr_refcount; /* 内部使用 */
7 union // 指向数据区的指针
8 {
9 uchar* ptr;
10 short* s;
11 int* i;
12 float* fl;
13 double* db;
14 } data;
15 union // 行数
16 {
17 int rows;
18 int height;
19 };
20 union // 列数
21 {
22 int cols;
23 int width;
24 };
25 } CvMat;
CvMat 的创建方法
创建矩阵函数:
1 cvMat * cvCreateMat (int rows, int cols, int type);
rows:行数
cols:列数
CV_<比特数>(S|U|F)C<通道数>,比如 CV_32FC3 就表示 32 位浮点类型的 3 通道矩阵。
CvMat 中单个元素的存取方法
CV_MAT_ELEM () 来实现对矩阵某个元素的读取,如下代码访问矩阵中的第 3 行 2 列的元素:
1 float elem_3_2 = CV_MAT_ELEM (*mat, float, 3, 2);
指定的元素的值。
CV_MAT_ELEM_PTR () 来实现对矩阵某个元素的设置,该宏返回指向指定元素的指针,如下代码修改矩阵中的第 3 行 2 列的元素:
1 *((float *)CV_MAT_ELEM_PTR (*mat, 3, 2)) = elem_3_2;
获取到指向指定元素的指针后,还需要对这个指针进行强制转型方能正常使用。
CvMat 的遍历方法
对矩阵的遍历常常采用指针遍历法,如下代码展示了对一个 CvMat 矩阵的遍历:
1 // 此头文件包含图像IO函数的声明
2 #include "highgui.h"
3 // 此头文件包含基本的图像处理函数和高级计算机视觉算法
4 #include "cv.h"
5 #include <iostream>
6
7 #define R 10 // 矩阵行
8 #define C 10 // 矩阵列
9
10 using namespace std;
11
12 int main (void) {
13
14 // 创建 R 行 C 列 32位单通道浮点类型的矩阵
15 CvMat *m1 = cvCreateMat ( R, C, CV_32FC1 );
16
17 // 赋值变量
18 float s = 1.0f;
19 // 遍历矩阵并赋值
20 for (int i=0; i<R; i++) {
21 // 获取矩阵每行的行首地址,下面的data成员必须先取其ptr成员计算完偏移地址后,再强制转化为目标数据类型。
22 float *ptr = (float *)(m1->data.ptr + i * m1->step);
23 // 遍历子一维数组
24 for (int j=0; j<C; j++) {
25 ptr[j] = s++;
26 }
27 }
28
29 // 打印结果
30 for (int i=0; i<m1->rows; i++) {
31 float *ptr = (float *)(m1->data.ptr + i * m1->step);
32 for (int j=0; j<m1->cols; j++) {
33 printf("%7.2f", *ptr);
34 ptr++;
35 }
36 cout << endl;
37 }
38 cout << endl << endl;
39
40 getchar();
41
42 return 1;
43 }
运行结果:
说明
1. 一般尽量创建浮点矩阵( F 型 ),别的类型值可以向上转型后存放进去。
2. 如果要遍历的是字符型( U S 型 )矩阵,那么遍历指针一定要设定为字符型的,等到取出的时候再向上转型/存进的时候向下转型即可。