cvmat * m=cvcreate(4,4,cv_32fc1) 产生的matlab给矩阵赋值是赋值给m还是*m

1.初始化矩阵:
方式一、逐点赋值式:
CvMat* mat = cvCreateMat( 2, 2, CV_64FC1 );cvZero( mat );cvmSet( mat, 0, 0, 1 );cvmSet( mat, 0, 1, 2 );cvmSet( mat, 1, 0, 3 );cvmSet( mat, 2, 2, 4 );cvReleaseMat( &mat );
方式二、连接现有数组式:
double a[] = { 1, 2, 3, 4,5, 6, 7, 8,9, 10, 11, 12 };CvMat mat = cvMat( 3, 4, CV_64FC1, a ); // 64FC1 for double// 不需要cvReleaseMat,因为数据内存分配是由double定义的数组进行的。
2.IplImage 到cvMat的转换
方式一、cvGetMat方式:CvMat mathdr, *mat = cvGetMat( img, &mathdr );
方式二、cvConvert方式:CvMat *mat = cvCreateMat( img-&height, img-&width, CV_64FC3 );cvConvert( img, mat );// #define cvConvert( src, dst ) cvConvertScale( (src), (dst), 1, 0 )
3.cvArr(IplImage或者cvMat)转化为cvMat方式一、cvGetMat方式:int coi = 0;cvMat *mat = (CvMat*)if( !CV_IS_MAT(mat) ){mat = cvGetMat( mat, &matstub, &coi );if (coi != 0) // CV_ERROR_FROM_CODE(CV_BadCOI);}写成函数为:// This is just an example of function// to support both IplImage and cvMat as an inputCVAPI( void ) cvIamArr( const CvArr* arr ){CV_FUNCNAME( "cvIamArr" );__BEGIN__;CV_ASSERT( mat == NULL );CvMat matstub, *mat = (CvMat*)int coi = 0;if( !CV_IS_MAT(mat) ){CV_CALL( mat = cvGetMat( mat, &matstub, &coi ) );if (coi != 0) CV_ERROR_FROM_CODE(CV_BadCOI);}// Process as cvMat__END__;}
4.图像直接操作方式一:直接数组操作 int col, row,uchar b, g,for( y = 0; row & img-& y++ ){for ( col = 0; col & img-& col++ ){b = img-&imageData[img-&widthStep * row + col * 3]g = img-&imageData[img-&widthStep * row + col * 3 + 1];r = img-&imageData[img-&widthStep * row + col * 3 + 2];}}方式二:宏操作:int row,uchar b, g,for( row = 0; row & img-& row++ ){for ( col = 0; col & img-& col++ ){b = CV_IMAGE_ELEM( img, uchar, row, col * 3 );g = CV_IMAGE_ELEM( img, uchar, row, col * 3 + 1 );r = CV_IMAGE_ELEM( img, uchar, row, col * 3 + 2 );}}注:CV_IMAGE_ELEM( img, uchar, row, col * img-&nChannels + ch )
5.cvMat的直接操作数组的直接操作比较郁闷,这是由于其决定于数组的数据类型。
对于CV_32FC1 (1 channel float):CvMat* M = cvCreateMat( 4, 4, CV_32FC1 );M-&data.fl[ row * M-&cols + col ] = (float)3.0;
对于CV_64FC1 (1 channel double):CvMat* M = cvCreateMat( 4, 4, CV_64FC1 );M-&data.db[ row * M-&cols + col ] = 3.0;
一般的,对于1通道的数组:CvMat* M = cvCreateMat( 4, 4, CV_64FC1 );CV_MAT_ELEM( *M, double, row, col ) = 3.0;注意double要根据数组的数据类型来传入,这个宏对多通道无能为力。
对于多通道:看看这个宏的定义:#define CV_MAT_ELEM_CN( mat, elemtype, row, col ) /(*(elemtype*)((mat).data.ptr + (size_t)(mat).step*(row) + sizeof(elemtype)*(col)))if( CV_MAT_DEPTH(M-&type) == CV_32F )CV_MAT_ELEM_CN( *M, float, row, col * CV_MAT_CN(M-&type) + ch ) = 3.0;if( CV_MAT_DEPTH(M-&type) == CV_64F )CV_MAT_ELEM_CN( *M, double, row, col * CV_MAT_CN(M-&type) + ch ) = 3.0;更优化的方法是:#define CV_8U 0#define CV_8S 1#define CV_16U 2#define CV_16S 3#define CV_32S 4#define CV_32F 5#define CV_64F 6#define CV_USRTYPE1 7
int elem_size = CV_ELEM_SIZE( mat-&type );for( col = start_ col & end_ col++ ) {for( row = 0; row & mat-& row++ ) {for( elem = 0; elem & elem_ elem++ ) {(mat-&data.ptr + ((size_t)mat-&step * row) + (elem_size * col))[elem] =(submat-&data.ptr + ((size_t)submat-&step * row) + (elem_size * (col - start_col)))[elem];}}}
对于多通道的数组,以下操作是推荐的:for(row=0; row& mat-& row++){p = mat-&data.fl + row * (mat-&step/4);
for(col = 0; col & mat-& col++){*p = (float) row+*(p+1) = (float) row+col+1;*(p+2) =(float) row+col+2;p+=3;}}对于两通道和四通道而言: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);
6.间接访问cvMatcvmGet/Set是访问CV_32FC1 和 CV_64FC1型数组的最简便的方式,其访问速度和直接访问几乎相同cvmSet( mat, row, col, value );cvmGet( mat, row, col );举例:打印一个数组inline void cvDoubleMatPrint( const CvMat* mat ){int i,for( i = 0; i & mat-& i++ ){for( j = 0; j & mat-& j++ ){printf( "%f ",cvmGet( mat, i, j ) );}printf( "/n" );}}
而对于其他的,比如是多通道的后者是其他数据类型的,cvGet/Set2D是个不错的选择CvScalar scalar = cvGet2D( mat, row, col );cvSet2D( mat, row, col, cvScalar( r, g, b ) );
注意:数据不能为int,因为cvGet2D得到的实质是double类型。举例:打印一个多通道矩阵:inline void cv3DoubleMatPrint( const CvMat* mat ){int i,for( i = 0; i & mat-& i++ ){for( j = 0; j & mat-& j++ ){CvScalar scal = cvGet2D( mat, i, j );printf( "(%f,%f,%f) ", scal.val[0], scal.val[1], scal.val[2] );}printf( "/n" );}}
7.修改矩阵的形状&&cvReshape的操作经实验表明矩阵操作的进行的顺序是:首先满足通道,然后满足列,最后是满足行。注意:这和Matlab是不同的,Matlab是行、列、通道的顺序。我们在此举例如下:对于一通道:// 1 channelCvMat *mat,double data[] = { 11, 12, 13, 14,21, 22, 23, 24,31, 32, 33, 34 };CvMat* orig = &cvMat( 3, 4, CV_64FC1, data );//11 12 13 14//21 22 23 24//31 32 33 34mat = cvReshape( orig, &mathdr, 1, 1 ); // new_ch, new_rowscvDoubleMatPrint( mat ); // above// 11 12 13 14 21 22 23 24 31 32 33 34mat = cvReshape( mat, &mathdr, 1, 3 ); // new_ch, new_rowscvDoubleMatPrint( mat ); // above//11 12 13 14//21 22 23 24//31 32 33 34mat = cvReshape( orig, &mathdr, 1, 12 ); // new_ch, new_rowscvDoubleMatPrint( mat ); // above// 11// 12// 13// 14// 21// 22// 23// 24// 31// 32// 33// 34mat = cvReshape( mat, &mathdr, 1, 3 ); // new_ch, new_rowscvDoubleMatPrint( mat ); // above//11 12 13 14//21 22 23 24//31 32 33 34mat = cvReshape( orig, &mathdr, 1, 2 ); // new_ch, new_rowscvDoubleMatPrint( mat ); // above//11 12 13 14 21 22//23 24 31 32 33 34mat = cvReshape( mat, &mathdr, 1, 3 ); // new_ch, new_rowscvDoubleMatPrint( mat ); // above//11 12 13 14//21 22 23 24//31 32 33 34mat = cvReshape( orig, &mathdr, 1, 6 ); // new_ch, new_rowscvDoubleMatPrint( mat ); // above// 11 12// 13 14// 21 22// 23 24// 31 32// 33 34mat = cvReshape( mat, &mathdr, 1, 3 ); // new_ch, new_rowscvDoubleMatPrint( mat ); // above//11 12 13 14//21 22 23 24//31 32 33 34// Use cvTranspose and cvReshape( mat, &mathdr, 1, 2 ) to get// 11 23// 12 24// 13 31// 14 32// 21 33// 22 34// Use cvTranspose again when to recover
对于三通道// 3 channelsCvMat mathdr, *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)mat = cvReshape( orig, &mathdr, 3, 1 ); // new_ch, new_rowscv3DoubleMatPrint( mat ); // above// (111,112,113) (121,122,123) (211,212,213) (221,222,223)// concatinate in column first ordermat = cvReshape( orig, &mathdr, 1, 1 );// new_ch, new_rowscvDoubleMatPrint( mat ); // above// 111 112 113 121 122 123 211 212 213 221 222 223// concatinate in channel first, column second, row thirdmat = cvReshape( orig, &mathdr, 1, 3); // new_ch, new_rowscvDoubleMatPrint( mat ); // above//111 112 113 121//122 123 211 212//213 221 222 223// channel first, column second, row thirdmat = cvReshape( orig, &mathdr, 1, 4 ); // new_ch, new_rowscvDoubleMatPrint( mat ); // above//111 112 113//121 122 123//211 212 213//221 222 223// channel first, column second, row third// memorize this transform because this is useful to// add (or do something) color channelsCvMat* mat2 = cvCreateMat( mat-&cols, mat-&rows, mat-&type );cvTranspose( mat, mat2 );cvDoubleMatPrint( mat2 ); // above//111 121 211 221//112 122 212 222//113 123 213 223cvReleaseMat( &mat2 );
8.计算色彩距离我们要计算img1,img2的每个像素的距离,用dist表示,定义如下IplImage *img1 = cvCreateImage( cvSize(w,h), IPL_DEPTH_8U, 3 );IplImage *img2 = cvCreateImage( cvSize(w,h), IPL_DEPTH_8U, 3 );CvMat *dist = cvCreateMat( h, w, CV_64FC1 );比较笨的思路是:cvSplit-&cvSub-&cvMul-&cvAdd代码如下:IplImage *img1B = cvCreateImage( cvGetSize(img1), img1-&depth, 1 );IplImage *img1G = cvCreateImage( cvGetSize(img1), img1-&depth, 1 );IplImage *img1R = cvCreateImage( cvGetSize(img1), img1-&depth, 1 );IplImage *img2B = cvCreateImage( cvGetSize(img1), img1-&depth, 1 );IplImage *img2G = cvCreateImage( cvGetSize(img1), img1-&depth, 1 );IplImage *img2R = cvCreateImage( cvGetSize(img1), img1-&depth, 1 );IplImage *diff = cvCreateImage( cvGetSize(img1), IPL_DEPTH_64F, 1 );cvSplit( img1, img1B, img1G, img1R );cvSplit( img2, img2B, img2G, img2R );cvSub( img1B, img2B, diff );cvMul( diff, diff, dist );cvSub( img1G, img2G, diff );cvMul( diff, diff, diff);cvAdd( diff, dist, dist );cvSub( img1R, img2R, diff );cvMul( diff, diff, diff );cvAdd( diff, dist, dist );cvReleaseImage( &img1B );cvReleaseImage( &img1G );cvReleaseImage( &img1R );cvReleaseImage( &img2B );cvReleaseImage( &img2G );cvReleaseImage( &img2R );cvReleaseImage( &diff );
比较聪明的思路是int D = img1-&nC // D: Number of colors (dimension)int N = img1-&width * img1-& // N: number of pixelsCvMat mat1hdr, *mat1 = cvReshape( img1, &mat1hdr, 1, N ); // N x D(colors)CvMat mat2hdr, *mat2 = cvReshape( img2, &mat2hdr, 1, N ); // N x D(colors)CvMat diffhdr, *diff = cvCreateMat( N, D, CV_64FC1 ); // N x D, temporal buffcvSub( mat1, mat2, diff );cvMul( diff, diff, diff );dist = cvReshape( dist, &disthdr, 1, N ); // nRow x nCol to N x 1cvReduce( diff, dist, 1, CV_REDUCE_SUM ); // N x D to N x 1dist = cvReshape( dist, &disthdr, 1, img1-&height ); // Restore N x 1 to nRow x nColcvReleaseMat( &diff );
#pragma comment( lib, "cxcore.lib" )#include "cv.h"#include &stdio.h&int main(){CvMat* mat = cvCreateMat(3,3,CV_32FC1);cvZero(mat);//将矩阵置0//为矩阵元素赋值CV_MAT_ELEM( *mat, float, 0, 0 ) = 1.f;CV_MAT_ELEM( *mat, float, 0, 1 ) = 2.f;CV_MAT_ELEM( *mat, float, 0, 2 ) = 3.f;CV_MAT_ELEM( *mat, float, 1, 0 ) = 4.f;CV_MAT_ELEM( *mat, float, 1, 1 ) = 5.f;CV_MAT_ELEM( *mat, float, 1, 2 ) = 6.f;CV_MAT_ELEM( *mat, float, 2, 0 ) = 7.f;CV_MAT_ELEM( *mat, float, 2, 1 ) = 8.f;CV_MAT_ELEM( *mat, float, 2, 2 ) = 9.f;//获得矩阵元素(0,2)的值float *p = (float*)cvPtr2D(mat, 0, 2);printf("%f/n",*p);return 0;}
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:745312次
积分:9721
积分:9721
排名:第600名
原创:168篇
转载:204篇
评论:693条
(2)(4)(4)(5)(4)(4)(6)(9)(12)(1)(4)(11)(4)(5)(4)(1)(1)(3)(3)(2)(1)(2)(1)(1)(2)(3)(4)(1)(2)(2)(4)(2)(4)(2)(7)(2)(5)(4)(7)(12)(9)(1)(16)(18)(12)(19)(24)(4)(21)(25)(16)(25)(20)(2)(1)(2)OpenCV求矩阵的特征值和特征向量
第2页_Linux编程_Linux公社-Linux系统门户网站
你好,游客
OpenCV求矩阵的特征值和特征向量
来源:Linux社区&
作者:yunjin12
首先安转和配置OpenCV windows版,在此不赘述!
首先看看OpenCV中的矩阵运算的相关知识:CvMat(多通道矩阵)
CvMat的结构定义:
typedef struct CvMat{ /* CvMat 标识 (CV_MAT_MAGIC_VAL), 元素类型和标记 */ /* 以字节为单位的行数据长度*/int* /* 数据引用计数 */union{uchar*short*int*float*double*} /* data 指针 */#ifdef __cplusplusunion{};union{};# /* 行数 */ /* 列数*/#endif} CvMCvMat分配矩阵空间:CvMat* cvCreateMat(int rows, int cols, int type);例如:CvMat* M = cvCreateMat(4, 4, CV_32FC1);其中CV_32FC1表示32位浮点单通道矩阵
CvMat释放矩阵空间:CvMat* M = cvCreateMat(4, 4, CV_32FC1);cvReleaseMat(&M);
复制矩阵:CvMat* M1 = cvCreateMat(4, 4, CV_32FC1);CvMat* M2;M2 = cvCloneMat(M1);
初始化矩阵:double a[] = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}, {10, 11, 12} };CvMat Ma = cvMat(4, 3, CV_32FC1, a);//method 1CvMat Ma; cvInitMatHeader(&Ma, 3, 4, CV_32FC1, a);//method2
特征值分析(对称矩阵)CvMat* A = cvCreateMat(3, 3, CV_32FC1);CvMat* B = cvCreateMat(3, 3, CV_32FC1);CvMat* C = cvCreateMat(3, 1, CV_32FC1);cvEigenVV(A, B, C);//C是A的特征值(降序排列),而B则是A的特征向量(每行)
例如下面的例子(编译通过)
//获得特征向量//add by maozhaoyangvector&vector&double& & CImgClusterDemoView::GetEigenMat(const vector&vector&double& & &k){&&& CvMat* M = cvCreateMat(k.size(),k.size(),CV_64FC1);&&& cvZero(M);&&& for(int i = 0; i & k.size(); i++)&&&&&&& for(int j = 0; j & k.size(); j++)&&&&&&&&&&& cvmSet(M, i, j, k[i][j]);
&&& CvMat* E = cvCreateMat(k.size(), k.size(), CV_64FC1);&&& cvZero(E);
&&& CvMat* I = cvCreateMat(k.size(), 1, CV_64FC1);&&& cvZero(I);
&&& //从矩阵M中获取特征向量存入E(降序排列),特征值存入I&&& cvEigenVV(M, E, I);
&&& vector&double& a(k.size(),0);&&& vector& vector&double& & eigenMat(2,a);
&&& //取前两个最大的特征向量&&& for(int i = 0; i & 2; i++)&&&&&&& for(int j = 0; j & k.size(); j++)&&&&&&&&&&& eigenMat[i][j] = cvmGet(E,i,j);
&&& cvReleaseMat(&M);&&& cvReleaseMat(&E);&&& cvReleaseMat(&I);
&&& return eigenM} 2
相关资讯 & & &
& (01月18日)
& (01月18日)
& (01月28日)
& (01月18日)
& (01月18日)
图片资讯 & & &
   同意评论声明
   发表
尊重网上道德,遵守中华人民共和国的各项有关法律法规
承担一切因您的行为而直接或间接导致的民事或刑事法律责任
本站管理人员有权保留或删除其管辖留言中的任意内容
本站有权在网站内转载或引用您的评论
参与本评论即表明您已经阅读并接受上述条款cvmat_百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
评价文档:
1页免费10页免费9页免费10页1下载券3页免费3页免费15页3下载券6页2下载券5页2下载券4页1下载券
喜欢此文档的还喜欢10页免费10页1下载券10页1下载券7页1下载券1页免费
把文档贴到Blog、BBS或个人站等:
普通尺寸(450*500pix)
较大尺寸(630*500pix)
你可能喜欢OpenCV中IplImage类型, CvMat类型和Mat类型详解
opencv中常见的与图像操作有关的数据容器有Mat,cvMat和
IplImage,这三种类型都可以代表和显示图像,但是,Mat类型侧重于计算,数学性较高,openCV对Mat类型的计算也进行了优化。而
CvMat和IplImage类型更侧重于“图像”,opencv对其中的图像操作(缩放、单通道提取、图像阈值操作等)进行了优化。在
opencv2.0之前,opencv是完全用C实现的,但是,IplImage类型与CvMat类型的关系类似于面向对象中的继承关系。实际
上,CvMat之上还有一个更抽象的基类----CvArr,这在源代码中会常见。1. IplImageopencv中的图像信息头,该结构体定义:& typedef&struct&_IplImage&
&&&&int&nS&&&&/*&IplImage大小&*/
&&&&int&ID;&&&&/*&版本&(=0)*/
&&&&int&nC&&/*&大多数OPENCV函数支持1,2,3&或&4&个通道&*/&
&&&&int&alphaC&&/*&被OpenCV忽略&*/&
&&&&int&&&&/*&像素的位深度:&IPL_DEPTH_8U,&IPL_DEPTH_8S,&IPL_DEPTH_16U,&
&&&&&&&&&&&&&&&&IPL_DEPTH_16S,&IPL_DEPTH_32S,&IPL_DEPTH_32F&and&IPL_DEPTH_64F&可支持&*/&
&&&&char&colorModel[4];&/*&被OpenCV忽略&*/&
&&&&char&channelSeq[4];&/*&被OpenCV忽略&*/&
&&&&int&dataO&&&&&&/*&0&-&交叉存取颜色通道,&1&-&分开的颜色通道.&cvCreateImage只能创建交叉存取图像&*/&
&&&&int&&&&&&/*&0&-&顶—左结构,1&-&底—左结构&(Windows&bitmaps&风格)&*/&
&&&&int&&&&&&/*&图像行排列&(4&or&8).&OpenCV&忽略它,使用&widthStep&代替&*/&
&&&&int&&&&&&/*&图像宽像素数&*/&
&&&&int&&&&&/*&图像高像素数*/&
&&&&struct&_IplROI&*&&/*&图像感兴趣区域.&当该值非空只对该区域进行处理&*/&
&&&&struct&_IplImage&*maskROI;&/*&在&OpenCV中必须置NULL&*/&
&&&&void&*imageId;&&/*&同上*/&
&&&&struct&_IplTileInfo&*tileI&&/*同上*/&
&&&&int&imageS&&&&/*&图像数据大小(在交叉存取格式下imageSize=image-&height*image-&widthStep),单位字节*/&
&&&&char&*imageD&&&&/*&指向排列的图像数据&*/&
&&&&int&widthS&&&&&/*&排列的图像行大小,以字节为单位&*/&
&&&&int&BorderMode[4];&&&&&/*&边际结束模式,&被OpenCV忽略&*/&
&&&&int&BorderConst[4];&&&&/*&同上&*/&
&&&&char&*imageDataO&&&&/*&指针指向一个不同的图像数据结构(不是必须排列的),是为了纠正图像内存分配准备的&*/&
}&IplIdataOrder中的两个取值:交叉存取颜色通道是颜色数据排列将会是BGRBGR...的交错排列。分开的颜色通道是有几个颜色通道就分几个颜色平面存储。roi是IplROI结构体,该结构体包含了xOffset,yOffset,height,width,coi成员变量,其中xOffset,yOffset是x,y坐标,coi代表channel of interest(感兴趣的通道),非0的时候才有效。访问图像中的数据元素,分间接存储和直接存储,当图像元素为浮点型时,(uchar *) 改为 (float *): /*间接存取*/
IplImage*&img=cvLoadImage(&lena.jpg&,&1);
CvScalar&s;&&&&&&&/*sizeof(s)&==&img-&nChannels*/
s=cvGet2D(img,i,j);&&/*get&the&(i,j)&pixel&value*/
cvSet2D(img,i,j,s);&&&/*set&the&(i,j)&pixel&value*/
/*宏操作*/
IplImage*&&//malloc&memory&by&cvLoadImage&or&cvCreateImage
for(int&row&=&0;&row&& img-&&row++)
&&&&for&(int&col&=&0;&col&&&img-&&col++)
&&&&&&&&b&=&CV_IMAGE_ELEM(img,&UCHAR,&row,&col&*&img-&nChannels&+&0);&
&&&&&&&&g&=&CV_IMAGE_ELEM(img,&UCHAR,&row,&col&*&img-&nChannels&+&1);&
&&&&&&&&r&=&CV_IMAGE_ELEM(img,&UCHAR,&row,&col&*&img-&nChannels&+&2);
/*直接存取*/
IplImage*&&//malloc&memory&by&cvLoadImage&or&cvCreateImage
uchar&b,&g,&r;&//&3&channels
for(int&row&=&0;&row&& img-&&row++)
&&&&for&(int&col&=&0;&col&&&img-&&col++)
&&&&&&&&b&=&((uchar&*)(img-&imageData&+&row&*&img-&widthStep))[col&*&img-&nChannels&+&0];&
&&&&&&&&g&=&((uchar&*)(img-&imageData&+&row&*&img-&widthStep))[col&*&img-&nChannels&+&1];&
&&&&&&&&r&=&((uchar&*)(img-&imageData&+&row&*&img-&widthStep))[col&*&img-&nChannels&+&2];
}初始化使用IplImage&*,是一个指向结构体IplImage的指针:IplImage&*&cvLoadImage(const&char&*&filename,&int&iscolor&CV_DEFAULT(CV_LOAD_IMAGE_COLOR));&//load&images&from&specified&image&
IplImage&*&cvCreateImage(CvSize&size,&int&depth,&int&channels);&&//allocate&memory2.CvMat首先,我们需要知道,第一,在OpenCV中
没有向量(vector)结构。任何时候需要向量,都只需要一个列矩阵(如果需要一个转置或者共轭向量,则需要一个行矩阵)。第二,OpenCV矩阵的概
念与我们在线性代数课上学习的概念相比,更抽象,尤其是矩阵的元素,并非只能取简单的数值类型,可以是多通道的值。CvMat 的结构: typedef&struct&CvMat&
&&&&int&&&&&&&&&&
&&&&int&&&&&&&&&&&/*用字节表示行数据长度*/
&&&&int*&&&&&&/*内部访问*/
&&&&union&{
&&&&&&&&uchar*&&
&&&&&&&&short*&&s;
&&&&&&&&int*&&&&i;
&&&&&&&&float*&&
&&&&&&&&double*&
&&&&}&&&&&/*数据指针*/
&&&&&union&{
&&&&&&&&int&
&&&&&&&&int&
&&&&union&{
&&&&&&&&int&&&&
&&&&&&&&int&
}&CvM&/*矩阵结构头*/创建CvMat数据: CvMat&*&cvCreateMat(int&rows,&int&cols,&int&type);&/*创建矩阵头并分配内存*/
CV_INLine&CvMat&cvMat((int&rows,&int&cols,&int&type,&void*&data&CV_DEFAULT);&/*用已有数据data初始化矩阵*/
CvMat&*&cvInitMatHeader(CvMat&*&mat,&int&rows,&int&cols,&int&type,&void&*&data&CV_DEFAULT(NULL),&int&step&CV_DEFAULT(CV_AUTOSTEP));&/*(用已有数据data创建矩阵头)*/对矩阵数据进行访问: /*间接访问*/
/*访问CV_32F1和CV_64FC1*/
cvmSet(&CvMat*&mat,&int&row,&int&col,&double&value);
cvmGet(&const&CvMat*&mat,&int&row,&int&col&);
/*访问多通道或者其他数据类型:&scalar的大小为图像的通道值*/
CvScalar&cvGet2D(const&CvArr&*&arr,&int&idx0,&int&idx1);&//CvArr只作为函数的形参void&cvSet2D(CvArr*&arr,&int&idx0,&int&idx1,&CvScalar&value);
/*直接访问:&取决于数组的数据类型*/
/*CV_32FC1*/
CvMat&*&cvmat&=&cvCreateMat(4,&4,&CV_32FC1);
cvmat-&data.fl[row&*&cvmat-&cols&+&col]&=&(float)3.0;
/*CV_64FC1*/
CvMat&*&cvmat&=&cvCreateMat(4,&4,&CV_64FC1);
cvmat-&data.db[row&*&cvmat-&cols&+&col]&=&3.0;
/*一般对于单通道*/
CvMat&*&cvmat&=&cvCreateMat(4,&4,&CV_64FC1);
CV_MAT_ELEM(*cvmat,&double,&row,&col)&=&3.0;&/*double是根据数组的数据类型传入,这个宏不能处理多通道*/
/*一般对于多通道*/
if&(CV_MAT_DEPTH(cvmat-&type)&==&CV_32F)
&&&&CV_MAT_ELEM_CN(*cvmat,&float,&row,&col&*&CV_MAT_CN(cvmat-&type)&+&ch)&=&(float)3.0;&//&ch为通道值
if&(CV_MAT_DEPTH(cvmat-&type)&==&CV_64F)
&&&&CV_MAT_ELEM_CN(*cvmat,&double,&row,&col&*&CV_MAT_CN(cvmat-&type)&+&ch)&=&3.0;&//&ch为通道值
/*多通道数组*/
for&(int&row&=&0;&row&&&cvmat-&&row++)
&&&&p&=&cvmat&-&data.fl&+&row&*&(cvmat-&step&/&4);
&&&&for&(int&col&=&0;&col&&&cvmat-&&col++)&&&
&&&&{&&&&&&&
&&&&&&&&&*p&=&(float)&row&+&&&&&&&&
&&&&&&&&&*(p+1)&=&(float)row&+&col&+&1;&&&&&&&
&&&&&&&&&*(p+2)&=&(float)row&+&col&+&2;&&&&&&&
&&&&&&&&&p&+=&3;&&&&
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);复制矩阵操作:/*复制矩阵*/
CvMat*&M1&=&cvCreateMat(4,4,CV_32FC1);
CvMat*&M2;
M2=cvCloneMat(M1);3.MatMat是opencv2.0推出的处理图像的
新的数据结构,现在越来越有趋势取代之前的cvMat和lplImage,相比之下Mat最大的好处就是能够更加方便的进行内存管理,不再需要程序员手动
管理内存的释放。opencv2.3中提到Mat是一个多维的密集数据数组,可以用来处理向量和矩阵、图像、直方图等等常见的多维数据。class&CV_EXPORTS&Mat
/*..很多方法..*/
/*............*/
int&(Note&:目前还不知道flags做什么用的)
int&&&/*数据的维数*/
int&rows,&/*行和列的数量;数组超过2维时为(-1,-1)*/
uchar&*&&&/*指向数据*/
int&*&&&&/*指针的引用计数器;&阵列指向用户分配的数据时,指针为&NULL
/*&其他成员&*/&
};从以上结构体可以看出Mat也是一个矩阵头,默认不分配内存,只是指向一块内存(注意读写保护)。初始化使用create函数或者Mat构造函数,以下整理自opencv2.3.1 Manual:Mat(nrows,&ncols,&type,&fillValue]);&
M.create(nrows,&ncols,&type);
/*例子:*/
Mat&M(7,7,CV_32FC2,Scalar(1,3));&/*创建复数矩阵1+3j*/
M.create(100,&60,&CV_8UC(15));&/*创建15个通道的8bit的矩阵*/
/*创建100*100*100的8位数组*/
int&sz[]&=&{100,&100,&100};&
Mat&bigCube(3,&sz,&CV_8U,&Scalar:all(0));
/*现成数组*/
double&m[3][3]&=&{{a,&b,&c},&{d,&e,&f},&{g,&h,&i}};
Mat&M&=&Mat(3,&3,&CV_64F,&m).inv();
/*图像数据*/
Mat&img(Size(320,240),CV_8UC3);&
Mat&img(height,&width,&CV_8UC3,&pixels,&step);&/*const&unsigned&char*&pixels,int&width,&int&height,&int&step*/
/*使用现成图像初始化Mat*/
IplImage*&img&=&cvLoadImage(&greatwave.jpg&,&1);
Mat&mtx(img,0);&//&convert&IplImage*&-&&M&/*不复制数据,只创建一个数据头*/访问Mat的数据元素:/*对某行进行访问*/
M.row(3)&=&M.row(3)&+&M.row(5)&*&3;&/*第5行扩大三倍加到第3行*/
/*对某列进行复制操作*/
Mat&M1&=&M.col(1);
M.col(7).copyTo(M1);&/*第7列复制给第1列*/
/*对某个元素的访问*/
M.at&double&(i,j);&/*double*/
M.at(uchar)(i,j);&&/*CV_8UC1*/
Vec3i&bgr1&=&M.at(Vec3b)(i,j)&/*CV_8UC3*/
Vec3s&bgr2&=&M.at(Vec3s)(i,j)&/*CV_8SC3*/
Vec3w&bgr3&=&M.at(Vec3w)(i,j)&/*CV_16UC3*/
/*遍历整个二维数组*/
double&sum&=&0.0f;
for(int&row&=&0;&row&&&M.&row++)
&&&&const&double&*&Mi&=&M.ptr&double&(row);&
&&&&for&(int&col&=&0;&col&&&M.&col++)&&&&&&
&&&&&&&&sum&+=&std::max(Mi[j],&0.);
/*STL&iterator*/
double&sum=0;
MatConstIterator&double&&it&=&M.begin&double&(),&it_end&=&M.end&double&();
for(;&it&!=&it_&++it)&&&&
sum&+=&std::max(*it,&0.);Mat可进行Matlab风格的矩阵操作,如初始化的时候可以用initializers,zeros(), ones(), eye(). 除以上内容之外,Mat还有有3个重要的方法:Mat&mat&=&imread(const&String*&filename);&&&&&&&&&&&//&读取图像
imshow(const&string&frameName,&InputArray&mat);&&//&&&&显示图像
imwrite&(const&string&&filename,&InputArray&img);&&&&//储存图像4. CvMat, Mat, IplImage之间的互相转换IpIImage&-&&CvMat
/*cvGetMat*/
CvMat&*&mat&=&cvGetMat(img,&&matheader);
/*cvConvert*/
CvMat&*&mat&=&cvCreateMat(img-&height,&img-&width,&CV_64FC3);
cvConvert(img,&mat)
IplImage&-&&Mat
Mat::Mat(const&IplImage*&img,&bool&copyData=false);/*default&copyData=false,与原来的IplImage共享数据,只是创建一个矩阵头*/
IplImage*&iplImg&=&cvLoadImage(&greatwave.jpg&,&1);
Mat&mtx(iplImg);&/*&IplImage&*&-&&Mat,共享数据;&or&:&Mat&mtx&=&iplI*/
Mat&-&&IplImage
IplImage&iplimage&=&M;&/*只创建图像头,不复制数据*/
CvMat&-&&Mat
Mat::Mat(const&CvMat*&m,&bool&copyData=false);&/*类似IplImage&-&&Mat,可选择是否复制数据*/
Mat&-&&CvMat
例子(假设Mat类型的imgMat图像数据存在):
CvMat&cvMat&=&imgM/*Mat&-&&CvMat,&类似转换到IplImage,不复制数据只创建矩阵头

我要回帖

更多关于 matlab给矩阵赋值 的文章

 

随机推荐