OpenCV学习笔记(一)

Post date: 2012/4/10 上午 08:24:59

clever101 » 2008-07-22 23:36

出处:http://blog.csdn.net/clever101/archive/2008/07/22/2693101.aspx

因为要对一个矩阵求特征向量矩阵和特征值,本想使用MTL库,因为MTL从成熟程度和运算效率都有保证,没想到使用MTL库求特征向量矩阵和特征值还要依赖其它库,只好另辟蹊径了。幸好我找到了OpenCV,一个由intel资助的开源库,全称叫Open Source Computer Vision Library(大意就是开源计算机视觉库吧)。

要下载OpenCV库,可以从OpenCV中文站上下载,网址是:http://www.opencv.org.cn/index.php/Download。下载下来,我发现OpenCV库做得真的是很人性化——可以通过安装包进行安装。安装好后已经有支持VS 2005的解决方案文件了,你基本不用配置编译选项了。因为我只想里面的矩阵运算,因此这次我只编译了cxcore工程(呵呵,更深的学习还有待以后)。运行VS 2005的生成命令后生成库文件,debug模式下生成:cxcored.lib和cxcore100d.dll,release模式下生成cxcore100.dll和cxcore.lib(可以看到debug文件比release文件多了一个字母d)。

现在正式开始使用OpenCV库,要使用它,当然得把相关头文件拷出来,这里使用它的矩阵运算就是把安装目录下的cv文件夹拷出来,然后在你的程序中include。

使用库的第一个问题就是实现标准类型向库类型的转化(有时我就搞不懂,为何库不使用标准C的类型呢?比如char、int之类的,也许这个是出于效率方面的考虑吧)。OpenCV库求特征值和特征向量的函数是:

void cvEigenVV( CvArr* mat, CvArr* evects, CvArr* evals, double eps=0 );

mat

输入对称方阵。在处理过程中将被改变。

evects

特征向量输出矩阵, 连续按行存储

evals

特征值输出矩阵,按降序存储(当然特征值和特征向量的排序是同步的)。

eps

对角化的精确度 (典型地, DBL_EPSILON=≈10-15 就足够了)。

测试开始,建一个控制台程序,写一个测试函数:

void TestOpenCV(void)

{

// a为输入对称方阵

double a[5][5] =

{

{10.0, 1.0, 2.0, 3.0, 4.0},

{ 1.0, 9.0, -1.0, 2.0, -3.0},

{ 2.0, -1.0, 7.0, 3.0, -5.0},

{ 3.0, 2.0, 3.0, 12.0, -1.0},

{ 4.0, -3.0, -5.0, -1.0, 15.0}

};

// 构造输入方阵

CvMat SrcMatrix =cvMat(5,5, CV_64FC1,a);

double b[5][5] =

{

{0.0, 0.0, 0.0, 0.0, 0.0},

{ 0.0, 0.0, 0.0, 0.0, 0.0},

{ 0.0, 0.0, 0.0, 0.0, 0.0},

{ 0.0, 0.0, 0.0, 0.0, 0.0},

{ 0.0, 0.0, 0.0, 0.0, 0.0}

};

// 构造输出特征向量矩阵

CvMat ProVector =cvMat(5, 5, CV_64FC1, b);

// 构造输出特征值矩阵

double c[5] = {0.0, 0.0, 0.0, 0.0, 0.0};

CvMat ProValue = cvMat(5,1, CV_64FC1, c);

cvEigenVV(&SrcMatrix,&ProVector,&ProValue,1.0e-6F);

printf("\n");

int i =0;

int j =0;

for(i=0;i<5;i++)

{

for(j=0;j<5;j++)

printf("%f\t",cvmGet(&ProVector,i,j));

printf("\n");

}

for(i=0;i<5;i++)

{

printf("%f\n",cvmGet(&ProValue,i,0));

}

}

使用cvEigenVV函数要注意以下三点:

1. 构造对称方阵、特征向量输出矩阵和特征值输出矩阵必须分静态数组和动态开辟内存的数组,如果是静态数组如上面测试程序就可以使用上面的构造矩阵的方式,如果是动态开辟内存的数组,那么在构造矩阵类时就要使用下面的方式:

double** pfMatrix =new double*[nInBandNum];

double** pfVector=new double*[nInBandNum];

double* pProValue =new double[nInBandNum];

for(i=0;i<nInBandNum;i++)

{

pfMatrix[i]=new double[nInBandNum];

pfVector[i]=new double[nInBandNum];

pProValue[i]= 0.0;

}

// 初始化参数

for(i=0;i<nInBandNum;i++)

{

for(j=0;j<nInBandNum;j++)

{

pfMatrix[i][j]=0.0;

pfVector[i][j] = 0.0;

}

}

// 对输入对称方阵进行赋值,这一步放过

// 下面是构造输入方阵、特征向量矩阵和特征值矩阵

CvMat *pSrcMatrix = cvCreateMat(nBandNum, nBandNum, CV_64FC1);

CvMat *pProVector = cvCreateMat(nBandNum, nBandNum, CV_64FC1);

CvMat *pProValue = cvCreateMat(nBandNum,1, CV_64FC1);

for(i=0;i<nBandNum;i++)

{

cvmSet(pProValue,i,0,pfProVector[i]);

for(j=0;j<nBandNum;j++)

{

cvmSet(pSrcMatrix,i,j,pfMatrix[i][j]);

cvmSet(pProVector,i,j,pfVector[i][j]);

}

}

cvEigenVV(pSrcMatrix,pProVector,pProValue);

// 释放矩阵所占内存空间

cvReleaseMat(&pSrcMatrix);

cvReleaseMat(&pProVector);

cvReleaseMat(&pProValue);

呵呵,是不是感觉有点麻烦。我想究其原因,是因为OpenCV的矩阵类是一个一维数组,静态数组的地址是连续的,因为直接使用数组的首地址就可以访问其它数组元素,而多维动态数组的行与行的地址是不连续的,因此必须通过赋值进行构造。

2. 对称方阵、特征向量输出矩阵和特征值矩阵的行列必须保证匹配,比如对称方阵是5行5列,那么特征向量输出矩阵就是5行5列,特征值矩阵就是1行5列。

3. 特征值矩阵是降序排列的(从大到小)。

有兴趣的朋友可以看看cvEigenVV的源码是如何求特征向量矩阵和特征值矩阵,我大致看了一下,是使用雅可比法的。

参考网站及文献:

1. http://www.opencv.org.cn/index.php

2. OpenCV参考手册,中文翻译者:于仕琪,中科院自动化所自由软件协会,HUNNISH,阿须数码

clever101

OpenCV小学生

帖子: 6

注册: 2008-07-22 23:34

Shiqi Yu » 2008-07-23 9:25

不错,已经置顶

1. 发帖时请详细描述您遇到的问题,不要仅仅用“出错”,“有问题”,“不行”等没有信息含量的描述。

2. 标题中扼要描述你的问题,不要用“新手请教”之类没有信息含量的标题。

3. 不要“哭求”,“跪求”,男儿有泪不轻弹,男儿膝下有黄金。

4. 技术问题请发在板面,不要给我发送私人短信,其他问题欢迎给我发信。

Shiqi Yu

站点管理员

帖子: 2412

注册: 2006-09-27 17:58

地址: 蛇口

chai2010

OpenCV副教授

帖子: 775

注册: 2007-08-08 17:11

地址: 武汉

ollydbg23 » 2008-07-23 21:30

赞,这个帖子不错!

收藏了!

本人不接受站内私人短信讨论技术问题,有问题请发贴讨论!!!

提问的智慧 OpenCV论坛中文搜索 论坛精华区

ollydbg23

OpenCV教授

帖子: 3111

注册: 2008-04-13 9:16

cassel » 2008-09-17 16:04

描述的很清楚..

cassel

OpenCV高中生

帖子: 60

注册: 2008-01-23 11:16

Wain » 2008-09-20 1:38

期待后续更丰富的内容。

Automated Inspection of Deformable Object Assembly

Vision Inspection Group

Wain

OpenCV本科生

帖子: 143

注册: 2006-11-15 20:34

dengrf » 2008-10-23 20:05

慢慢看,慢慢学

dengrf

OpenCV小学生

帖子: 16

注册: 2008-10-22 21:02

opencvO » 2008-12-20 16:13

要下载OpenCV库,可以从OpenCV中文站上下载,网址是:http://www.opencv.org.cn/index.php/Download。下载下来,我发现OpenCV库做得真的是很人性化——可以通过安装包进行安装。安装好后已经有支持VS 2005的解决方案文件了,你基本不用配置编译选项了。因为我只想里面的矩阵运算,因此这次我只编译了cxcore工程(呵呵,更深的学习还有待以后)。运行VS 2005的生成命令后生成库文件,debug模式下生成:cxcored.lib和cxcore100d.dll,release模式下生成cxcore100.dll和cxcore.lib(可以看到debug文件比release文件多了一个字母d)。

不错的啊,学习

opencvO

OpenCV幼儿园宝宝

帖子: 3

注册: 2008-11-22 15:02

xiaoniug12 » 2009-04-22 13:45

怎么不写了?

xiaoniug12

OpenCV高中生

帖子: 52

注册: 2009-03-11 11:43

afei111 » 2009-05-17 16:27

感谢分享~~

afei111

OpenCV幼儿园宝宝

帖子: 4

注册: 2009-05-13 22:32

ziyunxun » 2009-07-18 14:15

类型的问题是因为图像处理需要复杂的数据结构吧..

如果你要做矩阵运算的话,为什么不使用

Matrix LAB( 矩阵实验室)

MATLAB呢?

上手快,操作方便..opencv搞矩阵属于它的工具项目..

ziyunxun

OpenCV高中生

帖子: 70

注册: 2009-04-11 9:39

ollydbg23 » 2009-07-28 22:24

ziyunxun 写道:

类型的问题是因为图像处理需要复杂的数据结构吧..

如果你要做矩阵运算的话,为什么不使用

Matrix LAB( 矩阵实验室)

MATLAB呢?

上手快,操作方便..opencv搞矩阵属于它的工具项目..

你想说什么?看不懂。。。

本人不接受站内私人短信讨论技术问题,有问题请发贴讨论!!!

提问的智慧 OpenCV论坛中文搜索 论坛精华区

ollydbg23

OpenCV教授

帖子: 3111

注册: 2008-04-13 9:16

clever101 » 2009-08-10 23:45

ziyunxun 写道:

类型的问题是因为图像处理需要复杂的数据结构吧..

如果你要做矩阵运算的话,为什么不使用

Matrix LAB( 矩阵实验室)

MATLAB呢?

上手快,操作方便..opencv搞矩阵属于它的工具项目..

你说的有一定道理。但是你也要看到MATLAB的缺陷,MATLAB一般限于实验室的算法仿真,用在大规模的软件开发不太现实。当然可以使用matcom工具将matlab代码转化为C++代码,但这种转化是有缺陷的,而且有些函数转不了。所以很多时候底层矩阵运算还得用C++来写。当然不可能自己从头写,只好利用一些开源库。

clever101

OpenCV小学生

帖子: 6

注册: 2008-07-22 23:34

ziyunxun » 2009-08-11 8:24

最近看到C++的matrix.h也可以做矩阵的运算之类的

,不过具体怎么样就不知道了

还有GNU的gsl库,这个似乎比较强大

虽然是GNU的,也有windows下面的可以使用

lz可以尝试

ziyunxun

OpenCV高中生

帖子: 70

注册: 2009-04-11 9:39

sbx19850629 » 2009-09-13 9:06

clever101 写道:

ziyunxun 写道:

类型的问题是因为图像处理需要复杂的数据结构吧..

如果你要做矩阵运算的话,为什么不使用

Matrix LAB( 矩阵实验室)

MATLAB呢?

上手快,操作方便..opencv搞矩阵属于它的工具项目..

你说的有一定道理。但是你也要看到MATLAB的缺陷,MATLAB一般限于实验室的算法仿真,用在大规模的软件开发不太现实。当然可以使用matcom工具将matlab代码转化为C++代码,但这种转化是有缺陷的,而且有些函数转不了。所以很多时候底层矩阵运算还得用C++来写。当然不可能自己从头写,只好利用一些开源库。

opencv定义自己的数据结构完全是为了很多算法实现的需要,如果使用C/C++基本的数据结构int/char/struct等,编制程序的复杂性会增加,程序的可读性也会变差,

这就是所谓的 程序=算法+数据结构 一个好的算法的实现,或者说一个好的库都依赖于一些好的数据结构定义。

个人理解,大家一起讨论啊

sbx19850629

OpenCV幼儿园宝宝

帖子: 5

注册: 2009-08-21 22:16

gaoxinand1

OpenCV小学生

帖子: 10

注册: 2010-01-21 20:02

tlzl0526 » 2010-04-07 14:18

不错 好好看

tlzl0526

OpenCV小学生

帖子: 17

注册: 2010-03-29 10:08

lhfz0530 » 2010-08-05 12:29

请问下有没有用过如何利用VC获取视频呢?我用的Ueye的工业摄像机...

lhfz0530

OpenCV高中生

帖子: 63

注册: 2010-07-30 10:40

difstone » 2011-02-24 22:35

感觉应该改一下标题,叫OpenCV里求特征值和特征向量

difstone

OpenCV初中生

帖子: 46

注册: 2010-08-02 14:01

feitianno3 » 2011-06-27 14:38

不错。

欢迎加入Q群13471159,讨论视觉、图像识别等相关技术。