1. 程式人生 > >稀疏矩陣在opencv中的應用(大矩陣運算速度過慢的問題,藉助SparseMat?)

稀疏矩陣在opencv中的應用(大矩陣運算速度過慢的問題,藉助SparseMat?)

大矩陣相乘的問題

很多演算法在執行的過程中產生的大矩陣往往包含很多0元素,我們下面的內容也是主要針對這類矩陣展開的。所以這個問題換一個說法就是 稀疏矩陣在opencv中的應用

可以看出,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庫的使用簡介

      sparse = dense.sparseView(epsilon,reference);
      dMat = MatrixXd(spMat);

所以大型矩陣相乘或者求解執行緒方程組都可以使用稀疏矩陣來做,速度會快很多!
但需要注意的是,演算法的速度問題從來都不是一個稀疏矩陣可以解決的,演算法本身的實現或者優化是最關鍵的模組!