2015-06-02 175 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

相关问题