第四章(下)


OpenCV中有多种选取区域的方法,罗列在表中。使用方法如下,其中比较值得注意的是乘法和除法。

 

 

此外,它还有更多的功能

稀疏矩阵

The cv::SparseMat class is used when an array is likely to be very large compared to                       SparseMat(稀疏矩阵)在一个矩阵的绝大部分都非零的时候使用。也正因此,

the  number  of  nonzero  entries.  This  situation  often  arises  in  linear  algebra  with                   SparseMat(稀疏矩阵)节省空间,并且有特殊的用途。

sparse matrices, but it also comes up when one wishes to represent data, particularly                                

histograms,  in  higher-dimensional  arrays,  since  most  of  the  space  will  be  empty  in

many practical applications. A sparse representation stores only data that is actually

present  and  so  can  save  a  great  deal  of  memory.  In  practice,  many  sparse  objects

would be too huge to represent at all in a dense format. The disadvantage of sparse                          但是,SparseMat(稀疏矩阵)的不利在于基于它的计算比较慢。

representations  is  that  computation  with  them  is  slower  (on  a  per-element  basis).

This last point is important, in that computation with sparse matrices is not categori‐

cally slower, as there can be a great economy in knowing in advance that many oper‐

ations need not be done at all.。

 

普通Mat和稀疏Mat最大的区别,就是其中的元素是如何保存的。稀疏Mat提供4中能够不同的访问方法:

cv::SparseMat::ptr() cv::SparseMat::reft

和cv::SparseMat::value 和cv::SparseMat::find

 

其中

从v::SpareseMat::ptr用于创建一维矩阵。

最简单实用方法:

uchar* cv::SparseMat::ptr(int i0,bool creatMissing,size_t* hashval=0);

如果已经创建,那么将指向这个区域;如果没有指向,否则为NULL.如果当createMissing开着的话,就会创建一个原始的ceateMissing.

 

SpareseMat::ref<>()用于创建一个reference.

可以这样来使用

a_sprse_mat.ref<float>(i0,i1) += 1.0f;

这种使用方法是非常经典的。

什么常用的cv::SparseMagt::value<>()的使用方法和ref是完全一样。但是它返回的是值而不是矩阵。

 

最后cv::SarseMat::find<>(),它返回的是requested object。它的返回结果是只读的。

 

那么让我们拿出一个例子来说明说有的问题吧:

#include "stdafx.h"
#include <iostream>
#include "opencv2/opencv.hpp"
using namespace cv;
using namespace std;
 
int main(int argc, char* argv[])
{
    // Create a 10x10 sparse matrix with a few nonzero elements
    //
    int size[] = {10,10};
    cv::SparseMat sm( 2, size, CV_32F );
    forint i=0; i<10; i++ ) {           // Fill the array
        int idx[2];
        idx[0= size[0* rand();
        idx[1= size[1* rand();
        sm.ref<float>( idx ) += 1.0f;
    }
    // Print out the nonzero elements
    //
    cv::SparseMatConstIterator_<float> it     = sm.begin<float>();
    cv::SparseMatConstIterator_<float> it_end = sm.end<float>();
    for(; it != it_end; ++it) {
        const cv::SparseMat::Node* node = it.node();
        printf(" (%3d,%3d) %f\n", node->idx[0], node->idx[1], *it );
    }
    waitKey();
}
    

 

通过这个例子可以看出,SparseMat是一个更加类似于hashtable的东西。在添加数据的时候,直接

 sm.ref<float>( idx ) += 1.0f;

而在读取数据的时候,最好采用 迭代器 的方式,

 cv::SparseMatConstIterator_<float> it     = sm.begin<float>();

这个例子就已经取到值了。注意其中你给的Node作为迭代器的存在。

4个函数的具体用法可以参看表格。上面的例子已经能够说明一类的问题。

 

cv::Mat 和 cv::SpareseMat还有一种模板写作的方法。

可以改写成

cv::Mat_<Vec2f> m(10,10);

以及

cv::SparseMat_<float> sm(ndim,size);


 





posted on 2022-12-03 15:31  jsxyhelu  阅读(27)  评论(0编辑  收藏  举报

导航