2015-06-02 203 views
1

有沒有方法可以獲取2D SparseMat的特定行的所有非零的索引,而無需循環遍歷行?OpenCV稀疏矩陣:如何獲得行/列中非零元素的索引

以下代碼使用循環打印第y行的結果。

for(int x = 0; x < sparse_mat.size(1); x++) 
{ 
    if(sparse_mat.ref<int>(y,x) != 0) 
      std::cout<<x<<std::endl; 
} 

非常感謝您的任何建議!

回答

0

我沒有OpenCV的,但通過閱讀documentation我發現這個例子:

// prints elements of a sparse floating-point matrix 
// and the sum of elements. 
SparseMatConstIterator_<float> 
    it = sparse_mat.begin<float>(), 
    it_end = sparse_mat.end<float>(); 
double s = 0; 
int dims = sparse_mat.dims(); 
for(; it != it_end; ++it) 
{ 
    // print element indices and the element value 
    const SparseMat::Node* n = it.node(); 
    printf("("); 
    for(int i = 0; i < dims; i++) 
     printf("%d%s", n->idx[i], i < dims-1 ? ", " : ")"); 
    printf(": %g\n", it.value<float>()); 
    s += *it; 
} 
printf("Element sum is %g\n", s); 

與下列一起:

如果運行這個循環中,你會發現,元素未按邏輯順序(辭典等等)列舉 。它們以相同的 順序存儲在散列表中(半隨機)。您可能會收集指向節點的指針,並對它們進行排序以獲得正確的排序順序 。但是請注意,向矩陣添加更多元素時,指向節點的指針可能會變爲無效 。這可能由於 可能的緩衝區重新分配而發生。

這意味着(有點顯式地)數據存儲在散列表中而不是索引和值的向量,或者像Eigen。它應該使您能夠篩選節點而不是特定的行;像

for(; it != it_end; ++it) 
{ 
    const SparseMat::Node* n = it.node(); 
    if(n->idx[ROW_INDEX]) 
     std::cout << n->idx[COL_INDEX] << std::endl; 
} 

更換ROW_INDEXCOL_INDEX因此,我不知道相關的訂單。

+1

嗨。感謝你的回答。但我認爲,如果節點總數大於列數,解決方案更糟糕:您的解決方案遍歷所有節點,而我在問題中提出的解決方案迭代一行。 – Khue

+0

是的,但仔細閱讀[documentation](http://docs.opencv.org/master/dd/da9/classcv_1_1SparseMat.html#a0e1e95540e8cc75976bb4be97dc2203e)。如果你指出一個不存在的索引,'ref'會創建一個節點。你可能想要使用'ptr'來給你[控制](http://docs.opencv.org/master/dd/da9/classcv_1_1SparseMat.html#a810b96cf23e3cc816e7f99473b81b513)來決定是否要創建一個缺失的節點。 –

+0

好點。但是,這並沒有真正回答我的問題:(也許這樣的解決方案不存在:( – Khue

相關問題