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 ); for( int 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);