OpenCV图像、矩阵、数组

一、结构

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)


本文转自:http://www.cnblogs.com/softec/archive/2010/03/16/1687637.html

 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值