烦人的矩阵

来源:互联网 发布:网络危机公关处理公司 编辑:程序博客网 时间:2024/05/30 13:41

最近老师给布置的任务需要处理矩阵,之前都没怎么写过完整程序的小白着实因为矩阵的问题困扰了好久。编程基础很差,于是问题也都没什么技术含量,姑且记录下来给自己看吧。

这个程序的任务太简单了,就是生成bow(bag of words,词袋)模型。bow是什么意思呢?比如有一个字典,有这么几个词["我","喜欢","你","可能"],那么“我喜欢你”这一句话就可以表示为{1, 1, 1, 0}这样的一个数组。也就是说,词袋模型可以将输入的句子变成一个数字序列,同时需要注意的是词袋模型是无序的。比如“我喜欢你”和“你喜欢我”会得到同一种表示,虽说这两者有所不同,但是将其归类为“表白”也是可以的。正是因此,词袋模型在机器学习上有其广泛的应用。

在我要写的程序里,一个视频有M个感兴趣点,每个感兴趣点有N维,也就是一个M*N的矩阵。一个词典有L个“单词”,每个单词有N维,也就是一个L*N的矩阵。

对于输入视频的每一个点,要在字典中寻找和它距离(欧式距离)最近的点用来表示,也就是说1*L的向量里会出现一个“1”(参照我喜欢你的例子)。接着对每一个点重复此过程,最终就会得到一个1*L的行向量。这个行向量的所有数据加起来是多少呢?也就是点数M喽。


好了,终于要进入正题……

矩阵的操作可以分为读取和写入,矩阵可能来自文本,也可能来自MATLAB生成的.mat文件(比如我要处理的就是)。在这个过程中我遇到了以下几种工具:

  • Matio,Linux下的开源库,用于读取.mat文件
  • Vector,C++下的数据类型,用于保存向量
  • CvMat,opencv中的数据类型,用于矩阵运算
接下来,就分别介绍一下这几种工具吧。

1、Matio

这是sourceforge上的一个开源项目,链接是:戳这里。项目提供了详细的pdf文档,在源代码的documentation文件夹中也附有详细的函数使用方法。

简单来说,要用Matio读取.mat文件,可以分为以下几步:

a、一个mat文件(废话……)

b、声明一个mat文件的指针,一个mat内容的指针

c、使用matio.h中提供的Mat_Open函数打开mat文件,Mat_VarRead函数读取内容

d、释放mat文件,mat内容

具体的代码实现其实很简单:

mat_t *matfp;                               //mat文件指针matvar_t *dictvar;                          //mat内容指针matfp = Mat_Open(argv[2], MAT_ACC_RDONLY);  //指定mat文件路径及打开方式if (NULL == matfp) {        cout<<"Can't open the dictionary generated by matlab!";        return EXIT_FAILURE;}
dictvar = Mat_VarRead(matfp, "dictionary");//对mat内容进行操作Mat_VarFree(dictvar);                       //释放mat内容Mat_Close(matfp);                           //释放mat文件

如果想使用mat中的数据,可以参照matio项目页面中的wiki,最简单的方法就是数据转换:

const double *dictData = static_cast<const double*>(dictvar->data);
不过需要注意,dictData是一个数组指针,访问索引时候需要注意,dictData[j * DICT_SIZE + i]访问的是mat变量里的第i行第j列数据。


2、Vector

vector是C++中的一个容器,使用之前需要包含头文件<vector>。对容器的使用大概分为以下几个步骤(参考了这里点击打开链接):

a、包括头文件

b、创建Vector对象

c、尾部插入或直接插入元素

d、使用下标或迭代器访问元素

需要注意的是用Vector实现二维向量的具体代码如下:

vector<vector<int> >vv(3, vector<int>(4));//这里,两个“>”间的空格是不可少的

接下来的访问则可以通过vv[i][j]完成。



3、CvMat

cvMat是OpenCV提供的数据结构,使用过程如下:

a、分配矩阵空间

b、为矩阵赋值,可采用矩阵整体初始化或对元素进行操作的方式

分配矩阵空间的格式如下

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


矩阵元素的类型格式为格式为CV_<bit_depth>(S|U|F)C<number_of_channels>。一个具体的例子如下
CvMat iIP = cvMat(128, 1, CV_32FC1, onestip);

这样将会生成一个128*1维的,类型为32位浮点型单通道矩阵。其中onestip是提前定义并赋值的float类型,且维数与iIP一致,用来初始化矩阵。


大概的使用方式就是这样,在最终的实现里使用了Matio读取.mat格式的字典,并用CvMat格式进行了bow的计算过程。

0 0