转载请注明出处:
http://blog.csdn.net/hust_sheng/article/details/79208772
大矩阵相乘的问题
很多算法在执行的过程中产生的大矩阵往往包含很多0元素,我们下面的内容也是主要针对这类矩阵展开的。所以这个问题换一个说法就是
稀疏矩阵在opencv中的应用
先给两个链接:
opencv的稀疏矩阵类SparseMat官方文档
opencv的稀疏矩阵类SparseMat讲解
可以看出,opencv确实支持稀疏矩阵,也就是
SparseMat
,用法和常规的
Mat
类似,但是
SparseMat
和
Mat
的底层实现是完全不一样的,前者采用的是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库的使用简介
sparse = dense.sparseView(epsilon,reference);
dMat = MatrixXd(spMat);
-
所以大型矩阵相乘或者求解线程方程组都可以使用稀疏矩阵来做,速度会快很多!
但需要注意的是,算法的速度问题从来都不是一个稀疏矩阵可以解决的,算法本身的实现或者优化是最关键的模块!