矩阵处理

1、矩阵的内存分配与释放

(1) 总体上:

OpenCV 使用C语言来进行矩阵操作。不过实际上有很多C++语言的替代方案可以更高效地完成。

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

矩阵按行-行方式存储,每行以4字节(32位)对齐.

(2) 为新矩阵分配内存:

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

type: 矩阵元素类型.

按CV_<bit_depth>(S|U|F)C<number_of_channels> 方式指定. 例如: CV_8UC1 、CV_32SC2.

示例:

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); // does not seem to be working properl

2、访问矩阵元素

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

(2) 间接访问:

cvmSet(M,i,j,2.0); // Set M(i,j)

t = cvmGet(M,i,j); // Get M(i,j)

(3) 直接访问(假设矩阵数据按4字节行对齐):

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

int n = M->cols;

float *data = M->data.fl;

data[i*n+j] = 3.0;

(4) 直接访问(当数据的行对齐可能存在间隙时 possible alignment gaps):

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

int step = M->step/sizeof(float);

float *data = M->data.fl;

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

(5) 对于初始化后的矩阵进行直接访问:

double a[16];

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

a[i*4+j] = 2.0; // Ma(i,j)=2.0;

3、矩阵/向量运算

(1) 矩阵之间的运算:

CvMat *Ma, *Mb, *Mc;

cvAdd(Ma, Mb, Mc); // Ma+Mb -> Mc

cvSub(Ma, Mb, Mc); // Ma-Mb -> Mc

cvMatMul(Ma, Mb, Mc); // Ma*Mb -> Mc

(2) 矩阵之间的元素级运算:

CvMat *Ma, *Mb, *Mc;

cvMul(Ma, Mb, Mc); // Ma.*Mb -> Mc

cvDiv(Ma, Mb, Mc); // 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); // 向量点乘: Va . Vb -> res

cvCrossProduct(&Va, &Vb, &Vc); // 向量叉乘: Va x Vb -> Vc

注意在进行叉乘运算时,Va, Vb, Vc 必须是仅有3个元素的向量.

(4) 单一矩阵的运算:

CvMat *Ma, *Mb;

cvTranspose(Ma, Mb); // 转置:transpose(Ma) -> Mb (注意转置阵不能返回给Ma本身)

CvScalar t = cvTrace(Ma); // 迹:trace(Ma) -> t.val[0]

double d = cvDet(Ma); // 行列式:det(Ma) -> d

cvInvert(Ma, Mb); // 逆矩阵:inv(Ma) -> 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); // solve (Ax=b) for x

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

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

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

CvMat* l = 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 = U D V^T

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

OpenCV矩阵运算的更多相关文章

  1. opencv矩阵运算(2)

    简单介绍 本篇承接上一篇.继续opencv下矩阵计算的函数使用. 计算矩阵的逆 注意:矩阵A是可逆矩阵的充分必要条件是行列式detA不等于0. 详细代码 double x[3][3] = {{1, 2 ...

  2. 第一周:读取XML深度数据并将其重建为三维点云

    本周主要任务:学习PCL点云库,掌握利用PCL对点云处理的方法 任务时间:2014年9月1日-2014年9月7日 任务完成情况:完成了读取单幅xml深度数据,并重建三维点云并显示 任务涉及基本方法: ...

  3. opencv中相关的矩阵运算

    一.矩阵Mat I,img,I1,I2,dst,A,B;double k,alpha;Scalar s;1.加法I=I1+I2;//等同add(I1,I2,I);add(I1,I2,dst,mask, ...

  4. opencv中Mat与IplImage,CVMat类型之间转换

    opencv中对图像的处理是最基本的操作,一般的图像类型为IplImage类型,但是当我们对图像进行处理的时候,多数都是对像素矩阵进行处理,所以这三个类型之间的转换会对我们的工作带来便利. Mat类型 ...

  5. OpenCV MAT基本图像容器

    参考博客: OpenCv中cv::Mat和IplImage,CvMat之间的转换 Mat - 基本图像容器 Mat类型较CvMat和IplImage有更强的矩阵运算能力,支持常见的矩阵运算(参照Mat ...

  6. C++矩阵运算库推荐

    最近在几个地方都看到有人问C++下用什么矩阵运算库比较好,顺便做了个调查,做一些相关的推荐吧.主要针对稠密矩阵,有时间会再写一个稀疏矩阵的推荐. Armadillo:C++下的Matlab替代品 地址 ...

  7. 图像储存容器Mat[OpenCV 笔记11]

    IplImage 与 Mat IplImage是OpenCV1中的图像存储结构体,基于C接口创建.在退出之前必须release,否则就会造成内存泄露.在一些只能使用C语言的嵌入式系统中,不得不使用. ...

  8. OpenCV(2)-Mat数据结构及访问Mat中像素

    Mat数据结构 一开始OpenCV是基于C语言的,在比较早的教材例如<学习OpenCV>中,讲解的存储图像的数据结构还是IplImage,这样需要手动管理内存.现在存储图像的基本数据结构是 ...

  9. OpenCV 2 Computer Vision Application Programming Cookbook读书笔记

    ### `highgui`的常用函数: `cv::namedWindow`:一个命名窗口 `cv::imshow`:在指定窗口显示图像 `cv::waitKey`:等待按键 ### 像素级 * 在灰度 ...

随机推荐

  1. VMware中的桥接模式、NAT(网络地址转换模式)、Host-only(主机模式):转自:http://blog.chinaunix.net/uid-11798538-id-3061551.html

    其中VMnet1是虚拟机Host-only模式的网络接口,VMnet8是NAT模式的网络接口,这些后面会详细介绍.在个虚拟交换机,分别是-个虚拟机交换机,而在VMware Workstation 5以 ...

  2. [Flask]学习杂记一 Hello程序

    这几天买了本  <Flask Web开发:基于Python的Web应用开发实战>,之前也用过flask 但是不怎么系统,有时候需要搭建一些临时的测试服务,用falsk比较方面,一个文件就可 ...

  3. [Vim]vim学习笔记--多个文件打开,切换,关闭

    一种情况是在shell中用vim打开多个文件,另一种是在vim编辑器中打开多个文件 同时打开多个文件 vim file1 file2  打开文件并水平窗口显示 vim -o file1 file2 打 ...

  4. 剑指Offer——巧妙使用sort(List<T>,Comparator<? super T>)比较器

    剑指Offer--巧妙使用sort(List<T>,Comparator<? super T>)比较器 先入为主 package cn.edu.ujn.offersword; ...

  5. webStorm破解

    B4A73YYJ-eyJsaWNlbnNlSWQiOiI0M0I0QTczWVlKIiwibGljZW5zZWVOYW1lIjoibGFuIHl1IiwiYXNzaWduZWVOYW1lIjoiIiw ...

  6. javascript之类型转换

    JavaScript是一种无类型语言,但同时JavaScript提供了一种灵活的自动类型转换的处理方式.基本规则是,如果某个类型的值用于需要其他类型的值的环境中,JavaScript就自动将这个值转换 ...

  7. <<精通iOS开发>>第14章例子代码彻底清除警告

    大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请多提意见,如果觉得不错请多多支持点赞.谢谢! hopy ;) 上一篇我们解决了<<精通iOS开发>> ...

  8. Java并发框架——同步状态的管理

    整个AQS框架核心功能都是围绕着其32位整型属性state进行,一般可以说它表示锁的数量,对同步状态的控制可以实现不同的同步工具,例如闭锁.信号量.栅栏等等.为了保证可见性此变量被声明为volatil ...

  9. 最简单的基于libVLC的例子:最简单的基于libVLC的视频播放器(图形界面版)

    ===================================================== 最简单的基于libVLC的例子文章列表: 最简单的基于libVLC的例子:最简单的基于lib ...

  10. Android开发学习之路--Activity之Intent

    窗外再次飘起了小雪,还有1周就过年了,2016年即将到来,来年不知道自己将身处何处,船到桥头自然直吧.还是继续学习吧,上次学习了Activity,那么如果是两个Activity之间,怎么从一个Acti ...