简单的方法
利用CV_MAT_ELEM()宏存取矩阵元素
elemtype CV_MAT_ELEM( mat, elemtype, row, col )
mat: 传入矩阵
elemtype: 待提取的元素类型
row: 行
col: 列
//矩阵的取 void accessMat(void) { float vals[]={0.32, 1.55, 2.24, 6.54}; CvMat mat=cvMat(2, 2, CV_32FC1, vals); for (int i=0; i<mat.width; i++)//列 { for (int j=0; j<mat.height; j++)//行 { float elem=CV_MAT_ELEM(mat, float, j, i); cout<<elem<<" "; } cout<<endl; } }
//矩阵的存取 void accessMat(void) { float vals[]={0.32, 1.55, 2.24, 6.54}; CvMat mat=cvMat(2, 2, CV_32FC1, vals); for (int i=0; i<mat.width; i++)//列 { for (int j=0; j<mat.height; j++)//行 { CV_MAT_ELEM(mat, float, j, i)=0.0111;//存 float elem=CV_MAT_ELEM(mat, float, j, i);//取 cout<<elem<<" "; } cout<<endl; } }
类似宏
CV_MAT_ELEM_PTR( mat, row, col )
mat:传入矩阵
row:待返回元素的行
col:待返回元素的列
该宏和CV_MAT_ELEM()宏最重要的区别是后者在指针解引用之前将其转化为指定的类型。
如果需要同时读取数据和设置数据,可以直接调用CV_MAT_ELEM_PTR(),但在这种情况下,必须自己将指针转化为恰当的类型
*((float *)CV_MAT_ELEM_PTR(mat, j, i))=0.0111;//存 float *elem=(float *)CV_MAT_ELEM_PTR(mat, j, i);//取
这些宏在每次调用的时候都重新计算指针。这意味着要查找指向矩阵基本元素数据区的指针、计算目标数据在矩阵中的相对地址,然后将相对位置与基本位置相加,所以即使这些宏容易使用,但也不是存取矩阵的最佳方法。在计划顺序访问矩阵中的所有元素时,这种方法的缺点尤为突出。
####################################################
麻烦的方法
在“简单的方法中”讨论的两个宏仅仅适用于访问1维或2维的数组,OpenCV提供了处理多维数组的机制
指针访问矩阵结构 cvPtr*D
uchar* cvPtr1D(
const CvArr* arr,
int idx0,
int* type=NULL
);
uchar* cvPtr2D(
const CvArr* arr,
int idx0,
int idx1,
int* type=NULL
);
uchar* cvPtr3D(
const CvArr* arr,
int idx0,
int idx1,
int idx2,
int* type=NULL
);
uchar* cvPtrND(
const CVArr* arr,
int* idx,
int* type=NULL
int create_node = 1
unsigned* precalc_hashval = NULL
);
//矩阵的取 void accessMat(void) { float vals[]={0.32, 1.55, 2.24, 6.54}; CvMat mat=cvMat(2, 2, CV_32FC1, vals); for (int i=0; i<mat.width; i++)//列 { for (int j=0; j<mat.height; j++)//行 { float *elem=(float *)cvPtr2D(&mat, j, i);//取 cout<<*elem<<" "; } cout<<endl; } }
//矩阵的存取 void accessMat(void) { float vals[]={0.32, 1.55, 2.24, 6.54}; CvMat mat=cvMat(2, 2, CV_32FC1, vals); for (int i=0; i<mat.width; i++)//列 { for (int j=0; j<mat.height; j++)//行 { *((float *)cvPtr2D(&mat, j, i)) = 0.11;//存 float *elem=(float *)cvPtr2D(&mat, j, i);//取 cout<<*elem<<" "; } cout<<endl; } }
第一个参数表示为矩阵指针,紧跟其后的参数表示索引的整数值,最后一个是可选的参数,它表示输出值的类型。
对于cvPtrND()来说,第二个参数是一个指向一个整型数组的指针,这个数组中包含索引的合适数字。
如果仅仅是读取函数,可用另一个函数族cvGet*D
CvMat 和 IplImage元素函数
double cvGetReal1D(const CvArr* arr, int idx0);
double cvGetReal2D(const CvArr* arr, int idx0, int idx1);
double cvGetReal3D(const CvArr* arr, int idx0, int idx1, int idx2);
double cvGetRealND(const CvArr* arr, int* idx);
CvScalar cvGet1D(const CvArr* arr, int idx0);
CvScalar cvGet2D(const CVArr* arr, int idx0, int idx1);
CvScalar cvGet3D(const CvArr* arr, int idx0, int idx1, int idx2);
CVScalar cvGetND(const CvArr* arr, int* idx);
cvGet*D中有四个函数返回的是整型的,另外四个的返回值是CvScalar类型的。这意味着在使用这些函数的时候,会有很大的空间浪费。所以,只是在你认为用这些函数比较方便和高效率的时候才用到它们,否则,最好用cvPtr*D
(个人使用,目前看来,在存取IplImage类型的变量时 CvScalar类型还是很方便的)
cvSet*D和cvGet*D多少有些类似,它通过一次函数调用为一个矩阵或图像中的元素设置值,函数cvSetReal*D()函数和cvSet*D()可以用来设置矩阵或图像中元素的数值
为CvMat或者IplImage元素设定值的函数
void cvSetReal1D(CvArr* arr, int idx0, double value);
void cvSetReal2D(CvArr* arr, int idx0, int idx1, double value);
void cvSetReal3D(CvArr* arr, int idx0, int idx1, int idx2, double value);
void cvSetRealND(CvArr* arr, int* idx, double value);
void cvSet1D(CvArr* arr, int idx0, CvScalar value);
void cvSet2D(CvArr* arr, int idx0, int idx1, CvScalar value);
void cvSet3D(CvArr* arr, int idx0, int idx1, int idx2, CvScalar value);
void cvSetND(CvArr* arr, int* idx, CvScalar value);
cvmSet()和cvmGet()这两个函数用于处理浮点数单通道矩阵,so easy!!!
double cvmGet(const CvMat* mat, int row, int col);
void cvmSet(CvMat* mat, int row, int col, double value);
//矩阵的存取 void accessMat(void) { float vals[]={0.32, 1.55, 2.24, 6.54}; CvMat mat=cvMat(2, 2, CV_32FC1, vals); for (int i=0; i<mat.width; i++)//列 { for (int j=0; j<mat.height; j++)//行 { cvmSet(&mat, j, i, 0.11); //*((float *)cvPtr2D(&mat, j, i)) = 0.11;//存 //float *elem=(float *)cvPtr2D(&mat, j, i);//取 float elem=cvmGet(&mat, j, i); cout<<elem<<" "; } cout<<endl; } }
#############################################################3
恰当的方法 !!!
如果打算对数组中的每一个元素执行一些操作,使用自己的指针是尤为重要的(假设没有可以为你执行任务的OpenCV函数)
累加一个三通道矩阵中的所有元素