稀疏矩阵在opencv中的应用(大矩阵运算速度过慢的问题,借助SparseMat?)

转载请注明出处:http://blog.csdn.net/hust_sheng/article/details/79208772


大矩阵相乘的问题

很多算法在执行的过程中产生的大矩阵往往包含很多0元素,我们下面的内容也是主要针对这类矩阵展开的。所以这个问题换一个说法就是 稀疏矩阵在opencv中的应用

先给两个链接:
opencv的稀疏矩阵类SparseMat官方文档
opencv的稀疏矩阵类SparseMat讲解

可以看出,opencv确实支持稀疏矩阵,也就是SparseMat,用法和常规的 Mat 类似,但是 SparseMatMat 的底层实现是完全不一样的,前者采用的是hash表,后者就是常规的矩阵存储。

cv::SparseMat uses a hash table to store just the nonzero elements. That hash table is maintained automatically, so when the number of (nonzero) elements in the array becomes too large for efficient lookup, the table grows automatically.

cv::SparseMat is a hash table. Looking up objects in a hash table requires two steps: first, computing the hash key (in this case, from the indices), and second, searching a list associated with that key. Normally, that list will be short (ideally only one element), so the primary computational cost in a lookup is the computation of the hash key. If this key has already been computed (as with cv::SparseMat::hash(), which will be covered next), then time can be saved by not recomputing it. In the case of cv::SparseMat::ptr(), if the argument hashval is left with its default argument of NULL, the hash key will be computed. If, however, a key is provided, it will be used.

那么问题来了,SparseMat 是不能随意支持跟 Mat 一样的操作的(底层实现的差别),所以,真实情况是,opencv的 SparseMat 支持的操作非常有限,比如并不支持四则运算,这就很尴尬了…

  • 解决方案一

    自己借助SparseMat实现矩阵四则运算操作,比如矩阵相乘,因为opencv至少提供了稀疏矩阵的元素访问API。但怎么说呢,自己实现的话,效率是一个问题,还有就是难道要实现所有的矩阵运算吗?如果需要复杂的运算,比如求解线性方程组,就比较费劲了。

  • 解决方案二

    借助第三方库,比如 eigen

    好消息是opencv的底层矩阵运算就是使用的eigen库,所以opencv和eigen可以很方便的连通。opencv甚至给了两者矩阵对象相互转换的接口:cv2eigen和eigen2cv

    • eigen库的使用简介

      eigen库的基本使用

      eigen稠密矩阵转稀疏矩阵

      sparse = dense.sparseView(epsilon,reference);

      eigen稀疏矩阵转稠密矩阵

      dMat = MatrixXd(spMat);

所以大型矩阵相乘或者求解线程方程组都可以使用稀疏矩阵来做,速度会快很多!
但需要注意的是,算法的速度问题从来都不是一个稀疏矩阵可以解决的,算法本身的实现或者优化是最关键的模块!

你可能感兴趣的:(opencv)