zoukankan      html  css  js  c++  java
  • OpenCV 中的三大数据类型:CvMat 类型

    前言

      本文将介绍 OpenCV 中的矩阵结构 CvMat 并提供几个很常用的矩阵使用方法。

      更多的矩阵处理函数还请参阅相关资料。

    CvMat 的类型定义

     1 typedef struct CvMat
     2 {
     3     int type;    // 数据类型
     4     int step;    // 行长度
     5     int* refcount;    /* 内部使用 */
     6     int hdr_refcount;    /* 内部使用 */
     7     union    // 指向数据区的指针
     8     {
     9         uchar* ptr;
    10         short* s;
    11         int* i;
    12         float* fl;
    13         double* db;
    14     } data;
    15     union    // 行数
    16     {
    17         int rows;
    18         int height;
    19     };
    20     union    // 列数
    21     {
    22         int cols;
    23         int width;
    24     };
    25 } CvMat;

    CvMat 的创建方法

      创建矩阵函数:

    1 cvMat * cvCreateMat (int rows, int cols, int type);

      rows:行数

      cols:列数

      type:数据类型,其格式一般为 CV_<比特数>(S|U|F)C<通道数>,比如 CV_32FC3 就表示 32 位浮点类型的 3 通道矩阵。

    CvMat 中单个元素的存取方法

      1. 可以使用宏 CV_MAT_ELEM () 来实现对矩阵某个元素的读取,如下代码访问矩阵中的第 3 行 2 列的元素:

    1 float elem_3_2 = CV_MAT_ELEM (*mat, float, 3, 2);

      其中,mat是 CvMat * 类型,float 是类型说明,最后两个参数是元素的行和列,该宏返回指定的元素的值

      2. 可以使用宏 CV_MAT_ELEM_PTR () 来实现对矩阵某个元素的设置,该宏返回指向指定元素的指针,如下代码修改矩阵中的第 3 行 2 列的元素:

    1 *((float *)CV_MAT_ELEM_PTR (*mat, 3, 2)) = elem_3_2;

      需要说明的是,获取到指向指定元素的指针后,还需要对这个指针进行强制转型方能正常使用

    CvMat 的遍历方法

      如果遍历采用一个个取元素的方法,未免效率太慢。实际应用中,对矩阵的遍历常常采用指针遍历法,如下代码展示了对一个 CvMat 矩阵的遍历:

     1 // 此头文件包含图像IO函数的声明
     2 #include "highgui.h"
     3  // 此头文件包含基本的图像处理函数和高级计算机视觉算法
     4 #include "cv.h"
     5 #include <iostream>
     6 
     7 #define R 10    // 矩阵行
     8 #define C 10    // 矩阵列
     9 
    10 using namespace std;
    11 
    12 int main (void) {
    13     
    14     // 创建 R 行 C 列 32位单通道浮点类型的矩阵
    15     CvMat *m1 = cvCreateMat ( R, C, CV_32FC1 );
    16     
    17     // 赋值变量
    18     float s = 1.0f;
    19     // 遍历矩阵并赋值
    20     for (int i=0; i<R; i++) {
    21         // 获取矩阵每行的行首地址,下面的data成员必须先取其ptr成员计算完偏移地址后,再强制转化为目标数据类型。
    22         float *ptr = (float *)(m1->data.ptr + i * m1->step);
    23         // 遍历子一维数组
    24         for (int j=0; j<C; j++) {
    25             ptr[j] = s++;
    26         }
    27     }
    28 
    29     // 打印结果
    30     for (int i=0; i<m1->rows; i++) {
    31         float *ptr = (float *)(m1->data.ptr + i * m1->step);
    32         for (int j=0; j<m1->cols; j++) {
    33             printf("%7.2f", *ptr);
    34             ptr++;
    35         }
    36         cout << endl;
    37     }
    38     cout << endl << endl;
    39 
    40     getchar();
    41 
    42     return 1;
    43 }

      运行结果:

      

     说明

      1. 一般尽量创建浮点矩阵( F 型 ),别的类型值可以向上转型后存放进去。

      2. 如果要遍历的是字符型( U S 型 )矩阵,那么遍历指针一定要设定为字符型的,等到取出的时候再向上转型/存进的时候向下转型即可。

  • 相关阅读:
    多维数组,转化为一维数组多种解决方案
    word-wrap与word-break的区别,以及无效情况
    重温前端基础之-js排序算法
    重温前端基础之-css浮动之怪异现象
    重温前端基础之-css浮动与清除浮动
    重温前端基础之-css盒模型
    C# 应用
    C# 应用
    C# 应用
    C# 应用
  • 原文地址:https://www.cnblogs.com/scut-fm/p/3733917.html
Copyright © 2011-2022 走看看