OpenCV图像、矩阵、数组

来源:互联网 发布:农村淘宝商业计划书 编辑:程序博客网 时间:2024/05/01 14:16
转载自:http://www.cnblogs.com/softec/archive/2010/03/16/1687637.html

一、结构

IplImage
  |-- int  nChannels;     // Number of color channels (1,2,3,4)
  |-- int  depth;         // Pixel depth in bits:
  |                       //   IPL_DEPTH_8U, IPL_DEPTH_8S,
  |                       //   IPL_DEPTH_16U,IPL_DEPTH_16S,
  |                       //   IPL_DEPTH_32S,IPL_DEPTH_32F,
  |                       //   IPL_DEPTH_64F
  |-- int  width;         // image width in pixels
  |-- int  height;        // image height in pixels
  |-- char* imageData;    // pointer to aligned image data
  |                       // Note that color images are stored in BGR order 这就是传说中的数据矩阵
  |-- int  dataOrder;     // 0 - interleaved color channels,
  |                       // 1 - separate color channels
  |                       // cvCreateImage can only create interleaved images
  |-- int  origin;        // 0 - top-left origin,
  |                       // 1 - bottom-left origin (Windows bitmaps style)
  |-- int  widthStep;     // size of aligned image row in bytes
  |-- int  imageSize;     // image data size in bytes = height*widthStep
  |-- struct _IplROI *roi;// image ROI. when not NULL specifies image
  |                       // region  to be processed.
  |-- char *imageDataOrigin; // pointer to the unaligned origin of image data
  |                          // (needed for correct image deallocation)
  |
  |-- int  align;         // Alignment of image rows: 4 or 8 byte alignment
  |                       // OpenCV ignores this and uses widthStep instead
  |-- char colorModel[4]; // Color model - ignored by OpenCV

 

矩阵:

CvMat                      // 2维矩阵
  |-- int   type;          // 元素类型(uchar,short,int,float,double)
  |-- int   step;          // 一行所占字节长度
  |-- int   rows, cols;    // 尺寸大小
  |-- int   height, width; // 备用尺寸参照
  |-- union data;
     |-- uchar*  ptr;     // 针对unsigned char矩阵的数据指针
      |-- short*  s;       // 针对short矩阵的数据指针
      |-- int*    i;       // 针对integer矩阵的数据指针
      |-- float*  fl;      // 针对float矩阵的数据指针
      |-- double* db;      // 针对double矩阵的数据指针


CvMatND                    // N-维矩阵
  |-- int   type;          // 元素类型(uchar,short,int,float,double)
  |-- int   dims;          // 数组维数
  |-- union data;
  |   |-- uchar*  ptr;     // 针对unsigned char矩阵的数据指针
  |   |-- short*  s;       // 针对short矩阵的数据指针
  |   |-- int*    i;       // 针对integer矩阵的数据指针
  |   |-- float*  fl;      // 针对float矩阵的数据指针
  |   |-- double* db;      // 针对double矩阵的数据指针
  |
  |-- struct dim[];        // 每个维的信息
      |-- size;            // 该维内元素个数
      |-- step;            // 该维内元素之间偏移量

 

通用数组:

CvArr*     // 仅作为函数参数,说明函数接受多种类型的数组,例如:           //    IplImage*, CvMat* 或者 CvSeq*.            // 只需通过分析数组头部的前4字节便可确定数组类型

二、修改单个像素:

1.3通道时:CV_IMAGE_ELEM(image, unsigned char, i, j*3+k) = gray_val;            //0<=k<3

2.单通道时:CV_IMAGE_ELEM(image, unsigned char, i, j) = gray_val;

3.通用方法:CvScalar s;
                 s=cvGet2D(img,i,j); // get the (i,j) pixel value

                 s.val[0]=111;         //单通道就只有这个有效
                 s.val[1]=111;
                 s.val[2]=111;
                 cvSet2D(img,i,j,s);//set the (i,j) pixel value

 

三、图像到矩阵

方式一、cvGetMat方式:
CvMat mathdr, *mat = cvGetMat( img, &mathdr );
mathdr只是根据img生成一个矩阵头,而其数据指向img的数据。

但只是把原来图像img头变成了CvMat头,数据体部分并没有复制,所以如果此时Release了img,则再访问mat就会出现错误。


方式二、cvConvert方式:
CvMat *mat = cvCreateMat( img->height, img->width, CV_64FC3 );
cvConvert( img, mat );
// #define cvConvert( src, dst )  cvConvertScale( (src), (dst), 1, 0 )

 

四、从一幅图像中截出一小块,把它转成一维向量

 cvSetImageROI(srcImg,blockRect);//blockRect为CvRect类型
 cvCopy(srcImg,block);//srcImg为IplImage类型,block为CvMat类型
 cvResetImageROI(srcImg);
 CvMat vecHead,*vec;
 vec=cvReshape( block, &vecHead, 0, 1 );//vec是得到的一维向量

说明:

1 同样大小的IplImage和CvMat,IplImage->widthStep不等于CvMat->step;
2 cvGetMat和cvReshape都只生成一个新的矩阵头,而数据都指向原来的地址,所以是两个矩阵共有一组数据,这一点在使用中要注意,原来的数据撤消是否会影响后生成的矩阵的使用。
3 cvGetMat得到的矩阵的step,等于原来IplImage的widthStep,再调用cvReshape时会出错。
4 cvReshape是按行形成向量,如果想按列形成向量,就先调用cvTranspose对矩阵进行转置,再调用cvReshape.
5 用cvCopy可以在IplImage和CvMat之间转换,比cvGetMat好,但其数据必须是同样的type和size.
6 如果是不同的type之间转换,可以用cvScale.

 

五、矩阵元素操作

一般的,对于1通道的数组:
CvMat* M = cvCreateMat( 4, 4, CV_64FC1 );
CV_MAT_ELEM( *M, double, row, col ) = 3.0;
注意double要根据数组的数据类型来传入。

 

对于两通道和四通道而言:
CvMat* vector = cvCreateMat( 1, 3, CV_32SC2 );
CV_MAT_ELEM( *vector, CvPoint, 0, 0 ) = cvPoint(100,100);

CvMat* vector = cvCreateMat( 1, 3, CV_64FC4 );
CV_MAT_ELEM( *vector, CvScalar, 0, 0 ) = cvScalar(0,0,0,0);

 

六、数组到矩阵

// 3 channels
CvMat mathdr, *mat;
double data[] = { 111, 112, 113, 121, 122, 123,
211, 212, 213, 221, 222, 223 };
CvMat* orig = &cvMat( 2, 2, CV_64FC3, data );
//(111,112,113) (121,122,123)
//(211,212,213) (221,222,223)

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 孩子晚上不睡觉老哭怎么办? 4岁宝宝叛逆期怎么办 驾考紧张脚抖怎么办 驾考科目三紧张怎么办 孩子不自信容易紧张怎么办 在人多时候紧张怎么办 考科目二很紧张怎么办 明天出成绩很紧张怎么办 一紧张就射精了怎么办 孩子在幼儿园表现不好怎么办 小孩子在幼儿园表现的不好怎么办 学籍档案写错了怎么办 发展报告填错了怎么办 学生发展报告丢了怎么办 大一新生入学团员档案袋丢失怎么办 三年级孩子语文成绩差怎么办 运气不好时 我们该怎么办 猫走了财运变差怎么办 特别在意别人的眼光怎么办 入职两个月没有业绩怎么办 在学舞蹈中孩子怕疼怎么办 我生二胎怕疼怎么办 孩子的执行力差怎么办 怀孕三个月不想要孩子怎么办 生完孩子老是掉头发怎么办 5岁半宝宝有狐臭怎么办? 4岁宝宝脾气倔怎么办 小孩子摔到后脑勺吐了怎么办 学生报告册丢了怎么办 错过宝宝语言敏感期怎么办 父亲骂我很难听怎么办 90后父母催婚怎么办 和隔壁邻居吵架了怎么办 教师上课期间孩子出问题责任怎么办 孩子一考试妈妈就焦虑怎么办 妈妈爱发脾气孩子也发脾气怎么办 孩子对家人有抵触情绪怎么办 孩子因为没耐心哭闹怎么办 宝宝哭闹真是没耐心怎么办 对自己孩子没耐心怎么办 跳了把腰伤了怎么办