图像与大数组类型

Posted on 2020-05-27 15:32  金色的省略号  阅读(211)  评论(0编辑  收藏  举报

  动态可变存储

  Mat即矩阵(Matrix)的缩写

  大数组类型中最主要的是,cv::Mat,可以看成是OpenCV库, C++ 实现的核心内容;OpenCV库的绝大多数函数,或是cv::Mat的成员,或是以cv::Mat作为参数,或是返回值是cv::Mat,或是其一或是所有; cv::Mat一般用于任意维度的稠密数组,这个稠密的意思是与数组单元相对应,都有一个数据存放在内存,哪怕这个数组单元存放的是零;大多数的图像存储稠密数组;

  使用稀疏数组的是直方图,cv::SparseMat

  一、The cv::Mat 类,多维稠密数组

  cv::Mat类可以作为任意维度的数组使用,其数据可以看做是以按照栅格扫描顺序存储的n维数组;在一维数组中,元素是按顺序排列的;在一个二维数组中,数据按行组织的,每一行也按顺序排列;对于三维数组,所有的通道都被行填充,每一个通道同样按顺序排列;

  所有的矩阵都包含,一个表示它所包含数组类型的元素flag,一个表示其维度的元素dims,分别表示行列的数目的元素rows和cols(dims不大于2),一个指示数据真正存储位置的data指针,一个表示该内存区域有多少个引用的refcount元素;

  cv::Mat中的元素可以是一个简单的数字,也可以是多个数字,在包含多个数字的时候,它就被称为多通道数组;

  构造一个数组

  可以用cv::Mat实例化一个对象,构造一个数组,该数组没有大小也没有数据类型,可以利用对象调用Create()函数,参数为行、列、类型来分配数据;

cv::Mat m;
// Create data area for 3 rows and 10 columns of 3-channel 32-bit floats
m.create( 3, 10, CV_32FC3 );
// Set the values in the 1st channel to 1.0, the 2nd to 0.0, and the 3rd to 1.0
m.setTo( cv::Scalar( 1.0f, 0.0f, 1.0f ) );

  等同于

cv::Mat m( 3, 10, CV_32FC3, cv::Scalar( 1.0f, 0.0f, 1.0f ) );

   二、The cv::SparseMat 类: 稀疏数组

  cv::SpareMat使用哈希表来存储非0元素,这个哈希表会自动维护(自动增长)

  访问稀疏数组中的元素

  稀疏数组提供四种访问机制:cv::SparseMat::ptr(), cv::SparseMat::ref(), cv::SparseMat::value(), and cv::SparseMat::find()

  uchar* cv::SparseMat::ptr( int i0, bool createMissing, size_t* hashval=0 );  第二个参数createMissing表示这个元素应该被创建,如果这个元素已经在数组中定义,它将直接返回指向这个元素的指针,createMissing为真,这个元素将会被创建,并且一个合理的非0指针指向这个新的元素,如果参数hashval是默认的NULL,哈希key将被计算,如果主动提供 一个key,它将被使用 

  访问器模板函数SparseMat::ref<>()返回 一个 指向数组中特定元素的引用,它可以像这样调用 a_sparse_mat.ref<float>( i0, i1 ) += 1.0f;

  cv::SparseMat::value<>() 它将返回一个值,而不是返回值的引用,"只读方法 "

  cv::SparseMat::find<>(), 类似于 cv::SparseMat::ref<>() and cv::SparseMat::value<>() ,不同的是会返回一个请求对象的指针,但与cv::SparseMat::ptr()不一样,cv::SparseMat::find<>()的指针类型由模板指定的,是只读的 const 指针

    // 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);
    }
    //system("pause");