1.矩阵数据的存取
(1)简单的方法:
利用宏CV_MAT_ELEM()传入四个参数,矩阵、数据类型、列号、行号,返回一个指定的元素。
CvMat* mat = cvCreateMat( 5, 5, CV_32FC1 );
float element_3_2 = CV_MAT_ELEM( *mat, float, 3, 2 );
利用宏CV_MAT_ELEM_PTR()传入三个参数,矩阵、列号、行号,返回一个指定元素的指针。
CvMat* mat = cvCreateMat( 5, 5, CV_32FC1 );
float element_3_2 = 7.7;
*( (float*)CV_MAT_ELEM_PTR( *mat, 3, 2 ) ) = element_3_2;
这些宏容易使用,但不是最佳方法,每次调用的时候都要重新计算指针。不适于顺序访问矩阵元素。
(2)麻烦的方法
cvPtr*D和cvGet*D函数族可以直接N 维矩阵。
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
int create_node= 1
unsigned* precalc_hashval = NULL);
返回指向特定元素的指针。
用cvPtr*D得到特定的点,然后利用这个点进行指针算术运算,得到其它点的指针。
读取元素:double cvGetReal*D();
CvScalar cvGet*D();
在多通道矩阵中,通道是连续的,例如在一个二维3通道表示红、绿、蓝的矩阵中,数据元素
是按rgbrgbrgb...存储的,如果要想指针移动到下一通道只需加1,要移动到下一像素或者元素集
只需增加一定的偏移量,使其与通道数相等。
矩阵数组中的step元素:行的长度,是个字节指针。
数据元素是整型step/4+p移动到与p对应的下一行。
数据元素是double :step/8+p移动到与p对应的下一行。
cvSet*D() cvSetReal*D为IplImage、CvMat设定元素值。
cvmSet()、cvmGet()设定单通道图像的元素值。
(3)恰当的方法
定义自己的指针,并在矩阵中使用自己的方法。
在矩阵图像中,数据是按光栅扫描顺序存储的,列是变化最快的变量。
eg.累加一幅图像中的所有元素值。
float sum( const CvMat* mat ) {
float s = 0.0f;
for(int row=0; row<mat->rows; row++ ) {
const float* ptr = (const float*)(mat->data.ptr + row * mat->step);
for(int col=0; col<mat->cols; col++ ) {
s += *ptr++;
}
}
return( s );
}
(1)简单的方法:
利用宏CV_MAT_ELEM()传入四个参数,矩阵、数据类型、列号、行号,返回一个指定的元素。
CvMat* mat = cvCreateMat( 5, 5, CV_32FC1 );
float element_3_2 = CV_MAT_ELEM( *mat, float, 3, 2 );
利用宏CV_MAT_ELEM_PTR()传入三个参数,矩阵、列号、行号,返回一个指定元素的指针。
CvMat* mat = cvCreateMat( 5, 5, CV_32FC1 );
float element_3_2 = 7.7;
*( (float*)CV_MAT_ELEM_PTR( *mat, 3, 2 ) ) = element_3_2;
这些宏容易使用,但不是最佳方法,每次调用的时候都要重新计算指针。不适于顺序访问矩阵元素。
(2)麻烦的方法
cvPtr*D和cvGet*D函数族可以直接N 维矩阵。
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
int create_node= 1
unsigned* precalc_hashval = NULL);
返回指向特定元素的指针。
用cvPtr*D得到特定的点,然后利用这个点进行指针算术运算,得到其它点的指针。
读取元素:double cvGetReal*D();
CvScalar cvGet*D();
在多通道矩阵中,通道是连续的,例如在一个二维3通道表示红、绿、蓝的矩阵中,数据元素
是按rgbrgbrgb...存储的,如果要想指针移动到下一通道只需加1,要移动到下一像素或者元素集
只需增加一定的偏移量,使其与通道数相等。
矩阵数组中的step元素:行的长度,是个字节指针。
数据元素是整型step/4+p移动到与p对应的下一行。
数据元素是double :step/8+p移动到与p对应的下一行。
cvSet*D() cvSetReal*D为IplImage、CvMat设定元素值。
cvmSet()、cvmGet()设定单通道图像的元素值。
(3)恰当的方法
定义自己的指针,并在矩阵中使用自己的方法。
在矩阵图像中,数据是按光栅扫描顺序存储的,列是变化最快的变量。
eg.累加一幅图像中的所有元素值。
float sum( const CvMat* mat ) {
float s = 0.0f;
for(int row=0; row<mat->rows; row++ ) {
const float* ptr = (const float*)(mat->data.ptr + row * mat->step);
for(int col=0; col<mat->cols; col++ ) {
s += *ptr++;
}
}
return( s );
}