多通道的矩阵 —— 通道是连续的!!
要将指向该数据类型的指针移动到下一通道,我们只需要将其增加1。如果想访问下一个“像素”或者元素集,则需要一定的偏移量
矩阵的step元素是矩阵中行的长度,单位为字节。
#include "cv.h" #include "highgui.h" #include <IOSTREAM.H> int main(int argc,char** argv) { float vals[]={0.85,-0.46,0.36,1.33}; // 逐点赋值式 // CvMat* mat=cvCreateMat(2,2,CV_32FC1); // cvZero(mat); // cvmSet(mat,0,0,1); // cvmSet( mat, 0, 1, 2 ); // 用于处理浮点型单通道矩阵 等同于 cvSetReal2D(mat,0,1,2) // cvmSet( mat, 1, 0, 3 ); // cvmSet( mat, 2, 2, 4 ); // 连接现有数组 CvMat mat=cvMat(2,2,CV_32FC1,vals); // 不需要cvReleaseMat,因为数据内存分配是由double定义的数组进行的。 cout<<cvGetElemType(&mat)<<endl; // 存储在数组中的元素类型 cout<<cvGetDimSize(&mat,1)<<endl; // 矩阵在那个维数上的大小 unsigned e1=CV_MAT_ELEM(mat,float,1,0); // 简单方法 CV_MAT_ELEM() float *e2=(float *)CV_MAT_ELEM_PTR(mat,2,2); // 这些宏在每次调用的时候都重新计算指针 //cvReleaseMat(&mat); cout<<e1<<endl; return 0; } 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; } void saturate_sv(IplImage* img) { for(int y=0;y<img->height;y++) { uchar* ptr=(uchar*)(img->imageData+y*img->widthStep); // 当要处理的是矩阵时,必须对偏移进行调整 —— 因为数据指针可能是非字节类型 for(int x=0;x<img->width;x++) { ptr[3*x+1]=255; ptr[3*x+3]=255; } } }
原文:http://www.cnblogs.com/sprint1989/p/3804221.html