OpenCV学习 (二)  OpenCV基本操…


【矩阵处理】

1.       内存的分配与释放

因为OpenCV使用C语言来进行矩阵操作,但是用C++的替代方案可以更加高效地完成操作。

OpenCV中向量被当做是有一个维数为1N维矩阵。

矩阵按照行—行方式存储,每行4byte32bit)对齐。

2.       为新的矩阵分配内存

CvMat  *cvCreateMat(int  rows, int cols , int type);

其中  Type是矩阵元素的类型:

           CV(S|U|F)C方式指定

Eg CvMat * M=cvCreateMat(4,4,CV_32FC1);

3.       释放矩阵内存

CvMat  *M=cvCreateMat(4,4,CV_32FC1);

cvReleaseMat(&M);

4.       复制矩阵

CvMat *M1=cvCreateMat(4,4,CV_32FC1);

cvMat *M2;

M2=cvCloneMat(M1);

5.       初始化矩阵

double  a[]={1,2,3,4

                             5,6,7,8,

                             9,10,11,12}

CvMat  Ma=cvMat(3,4,CV_64FC1,a);

等价于

CvMat Ma;

cvInitMatHeader(&Ma,3,4,CV_64FC1,a);

6.       初始化矩阵为单位矩阵

CvMat *M=cvCreateMat(4,4,CV_32FC1);

cvSetIdentity(M);

7.       访问矩阵元素

假设我们现在需要访问一个2D浮点型矩阵的第(i,j)个单元

1.       间接访问

cvmSet(M,I,j,2.0); //设置M的(I,j)位置的值为2.0

t=cvmGet(M,I,j)

2.       直接访问(假设矩阵按照4字节对齐)

CvMat *M=cvCreateMat(4,4,CV_32FC1);

Int      =M->cols;

Float *data= M->data.f1;

Data[i*n+j]=3.0;

3.       直接访问(当数据的对齐可能存在间隙的时候)

CvMat *M=cvCreateMat(4,4,CV_32FC1);

Int  step=M->Setp/sizeof(float)

 

Float *data=M->data.f1;

(data+i*step)[j]=3.0;

4.       对于初始化后的矩阵进行直接访问

double a[16];

CvMat Ma=cvMat(3,4,CV_64FC1,a);

a[i*4+j]=2.0 

【基本运算】

1.       矩阵之间的运算

CvMat *Ma,*Mb,*Mc;

cvAdd(Ma,Mb,Mc);

cvSub(Ma,Mb,Mc)

cvMatMul(Ma,Mb,Mc);

2.       矩阵之间的元素级运算

CvMat  *Ma,*Mb,*Mc;

cvMulMaMb, Mc;

cvDiv(Ma,Mb,Mc);

cvAddS(Ma,cvScalar(-10.0),Mc); //Ma-10->Mc

3.       向量乘积

double  va[]={1,2,3};

double  vb[]={0,0,1};

double  vc[3];

CvMat Va=cvMat(3,1,CV_64FC1,va);

CvMat Vb=cvMat(3,1,CV_64FC1,vb);

CvMat Vc=cvMat(3,1,CV_64FC1,vc);

 

Double res=cvDotProduct(&Va&Vb)//向量点乘

cvCrossProduct&Va,&Vb,&vc;//向量叉乘

4.       单一矩阵的运算

CvMat * Ma* Mb

cvTranspos(Ma,Mb);//转置  transposeMa->Mb(转置不能返回给Ma本身

CvScalar t=cvTraceMa);

cvInvertMa,Mb;//逆矩阵 invMa->Mb

5.       非齐次线性方程求解

cvMat *A=cvCreateMat(3,3,CV_32FC1);

cvMat *x=cvCreateMat(3,1,CV_32FC1);

CvMat *b=cvCreateMat(3,1,CV_32FC1);

cvSolve(&A,&b,&x);  //solveAx=bfor  x

6.       特征值与特征向量(矩阵为方阵)

CvMat *A=cvCreateMat(3,3,CV_32FC1);

CvMat *E=cvCreateMat(3,3,CV_32FC1);

CvMat *I=cvCreateMat(3,1,CV_32FC1);

cvEigenVV(A,E,l);//l=A的特征值(递减顺序)  E=对应的特征向量(行向量)

7.       奇异值分解(SVD

CVMat *A=cvCreateMat(3,3,CV_32FC1)

     CvMat *U=cvCreateMat(3,3,CV_32FC1);

         CvMat *D=cvCreateMat(3,3,CV_32FC1);

         CvMat *V=cvCreateMat(3,3,CV_32FC1);

         cvSVD(A,D,U,V,CV_SVD_U_T|CV_SVD_V_T);//A=UDV^T

标志位使得矩阵U或者V按照转置的形式返回(若不转置可能运算出错)

 

OpenCV视频处理】

1.       从视频流中捕捉一帧画面

(1)       OpenCV支持从摄像头或者视频文件(AVI格式)中捕捉帧画面;

(2)       初始化一个摄像头捕捉器:

CvCapture *capture=cvCaptureFromCAM(0);

(3)       初始化一个视频文件捕捉器:

CvCapture *capture=cvCaptureFromAVI(“infile.avi”;

(4)       捕捉一帧画面:

IplImage *img=0;

If(!cvGrabFrame(capture)){  捕捉一帧

    Printf(“could not grav a frame\n\7”);

  Exit(0);

}

Img=cvRetrieveFrame(capture);   //检索捕捉到的这一帧给图像img

         若要从多个摄像头中同步捕捉画面,则必须先从每个摄像头中抓取一帧,紧接着要将被捕捉的帧画面恢复到一个IplImage *型图像中。(这个过程可以使用cvQueryFrame()函数一步完成;

(5)       释放视频流捕捉器:

cvReleaseCapture(&capture);

2.       获取/设置视频流信息

(1)       获取视频流设备信息:

CvQueryFrame(capture);//在读取视频流信息之前,要先执行此操作

int        frameH=(int)cvGetXaptureProperty(capture,CV_CAP_PROP_FRAME_HEIGHT);

int        frameW=(int)cvGetCaptureProperty(capture,CV_CAP_PROP_FRAME_WIDTH);

int        fps=(int)cvGetCaptureProperty(capture,CV_CAP_PROP_FPS);

int numFrames=(int)cvGetCaptureProperty(capture,CV_CAP_PROP_FRAME_COUNT);

fps仅仅对于视频文件有效,但是不太准确

(2)       获取帧图信息:

float posMsec=cvGetCaptureProperty(capture,CV_CAP_PROP_POS_MSEC):

int posFrames=(int) cvGetCaptureProperty(capture,CV_CAP_PROP_POS_FRAMES):

float posRatio=cvGetCaptureProperty(capture,CV_CAP_PROP_POS_AVI_RATIO);

(3)       设置从视频文件抓取第一帧画面的位置:

CvSetCapturePropertycapture,CV_CAP_PROP_POS_AVI_RATIO,(double)0.9;

3.       保存视频文件

(1)       初始化视频编写器:

CvVideoWriter *writer=0;

int isColor=1;

int fps=25;

int frameW =640;

int frameH=480;

write=cvCreateVideoWriter(“out.avi”,CV_FOURCC(‘P’,’I’,’M’,’1’),

                                                            fpscvSize(frameW,frameH),isColor)

其他的编码器代号包括:

其它的编码器代号包括: CV_FOURCC('P','I','M','1') = MPEG-1 codec CV_FOURCC('M','J','P','G') = motion-jpeg codec (does not work well) CV_FOURCC('M', 'P', '4', '2') = MPEG-4.2 codec CV_FOURCC('D', 'I', 'V', '3') = MPEG-4.3 codec CV_FOURCC('D', 'I', 'V', 'X') = MPEG-4 codec CV_FOURCC('U', '2', '6', '3') = H263 codec CV_FOURCC('I', '2', '6', '3') = H263I codec CV_FOURCC('F', 'L', 'V', '1') = FLV1 codec 若编码器代号为 -1,则运行时会弹出一个编码器选择框.

(2)       保持视频文件

IplImage *img=0;

Int nFrames=50;

for(i=0;i

{

    cvGrabFrame(capture);  //捕捉一帧

    img=cvRetrieveFrame(capture);//重新保存这帧图像在img

    //img=cvQueryFramecapture);

    cvWriteFrame(write,img);

                 

要查看所抓取到的帧画面,在循环中加入下列语句即可:

                    cvShowImage(“mainWin”img)

                    key=cvWaitKey(20);

注意显示的时候cvWaitkey不能小于20ms,否则画面的显示可能出错。

(3)       释放视频编写器

cvReleaseVideoWriter(&writer);

 

 

 

 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值