一、基础数据类型

1.(基础)固定大小矩阵类 matx

说明:

①    基础矩阵是我个人增加的描述,相对于Mat矩阵类(存储图像信息的大矩阵)而言。

②    固定大小矩阵类必须在编译期间就知晓其维度(矩阵大小)和类型(矩阵元素类型),用于某些特定的矩阵运算。数据存储也在栈上。

③    机器视觉领域,通常这些矩阵一般是2x2或3x3维度,较少有4x4维矩阵用于大量的转换工作。故Matx.hpp头文件被专门设计来容纳这类操作。

④    实际运用中单纯的运算matx矩阵操作是不执行的,通常都是将其转换为Mat矩阵或反向矩阵,使用上重命名机制(通过typedef关键字):Matx{1,2,3,4,6}{1,2,3,4,6}{f,d}

  例如:Matx33f 表示一个数据类型是float类型的3x3矩阵,类似地,Matx24d;

初始化两种方式:

  Ⅰ初始化元素列表:如源码中示例:求3x3矩阵的对称矩阵的每个元素之和(将Matx转换为Mat矩阵进行运算);

 //Ⅰ初始化列表方式进行初始化
 #include "opencv2/opencv.hpp"
 #include "iostream"

 using namespace cv;
 using namespace std;

 int main()
 {
     Matx33f m0(, , ,
                , , ,
                , , );
     cout << "A = " << endl;                //原矩阵
     cout << m0 << endl;
     cout << "AT = " << endl;
     cout << m0.t() << endl;                //原矩阵的转置
     cout << "Mat(AT) = " << endl;
     cout << Mat(m0.t()) << endl;           //转换到Mat类数组,便于其他操作

     cout << "Rank(A) = " << endl;
     cout << Mat(m0*m0.t()) << endl;        //求原矩阵的对称矩阵  =  原矩阵 X 原矩阵的转置矩阵

     cout << "The sum of rank(A)'s elemente is = " << endl;
     cout << sum(Mat(m0*m0.t())) << endl;   //Mat类通道未指定默认为1,sum()函数是依据通道数来计算矩阵数据的和
     ;
 }

Ⅰ初始化列表方式进行初始化

  ⅡC原生数组方式进行初始化:

 //Ⅱ C原生数组方式进行初始化
 #include "opencv2/opencv.hpp"
 #include "iostream"

 using namespace cv;
 using namespace std;

 int main()
 {
     , , ,
                    , , ,
                    , , };
     Matx33f m0(vals);
     cout << "A = " << endl;                //原矩阵
     cout << m0 << endl;
     cout << "AT = " << endl;
     cout << m0.t() << endl;                //原矩阵的转置
     cout << "Mat(AT) = " << endl;
     cout << Mat(m0.t()) << endl;           //转换到Mat类数组,便于其他操作

     cout << "Rank(A) = " << endl;
     cout << Mat(m0*m0.t()) << endl;        //求原矩阵的对称矩阵  =  原矩阵 X 原矩阵的转置矩阵

     cout << "The sum of rank(A)'s elemente is = " << endl;
     cout << sum(Mat(m0*m0.t())) << endl;   //Mat类通道未指定默认为1,sum()函数是依据通道数来计算矩阵数据的和
     ;
 }

Ⅱ C原生数组方式进行初始化

⑤    矩阵运算:加、减、缩放、乘、除、(矩阵)乘、转置

2.固定大小向量类 vector

说明:

①    图像处理方面固定大小向量类(直接使用基础数据类型利用模板技术(template class Vec<>)定义)用来描述多通道图像的像素类型信息的类。使用模板技术这允许特别高效的代码处理小的通用操作,例如基本的算数操作,通过[]操作符读取元素数据等。

OpenCVC++ STL中的向量类比对

Item

OpenCV

C++ STL

数据存储

加快程序的运行效率(节省动态申请的时间)

动态申请内存

容器类型

1.固定大小向量类在编译期间就知道维度的向量且维度相对小

2.通常情况下仅用来装载C语言中原生的int或float基本类型

可以装载任何类型甚至包含自定义的类类型。

④    向量运算:加,减,缩放,求负,两向量间比较③    在OpenCV中继承自Matx类,常用的单向量使用上重命名机制(通过typedef关键字):Vec{2, 3, 4, 6}{b, w, s, i, f, d};

  例如:Vec2i 表示一个列向量,向量元素有两个整型类型的数值,即2维列向量。

 #include "opencv2/opencv.hpp"
 #include "iostream"

 using namespace cv;
 using namespace std;

 int main()
 {
     Vec2i t(, );
     cout << t << endl;
     ;
 }

Vector 示例

二、源代码剖析

 /*
  * This program is free software; and the content, which just do a change in the order and text,
  * comes from offical documents. Only permission is hereby granted to learn and communication.
  *
  * Document: D:\Qt\opencvbuild3.40\install\include\opencv2\core\matx.hpp
  * Environment: QT 5.10.0 + OpenCV 3.4.0
  * place: Library, Wj  2018.03.17
 */

 #ifndef OPENCV_CORE_MATX_HPP
 #define OPENCV_CORE_MATX_HPP

 #ifndef __cplusplus
 #  error matx.hpp header must be compiled as C++
 #endif

 #include "opencv2/core/cvdef.h"
 #include "opencv2/core/base.hpp"
 #include "opencv2/core/traits.hpp"
 #include "opencv2/core/saturate.hpp"

 #ifdef CV_CXX11
 #include <initializer_list>
 #endif

 namespace cv
 {

 ////////////////////////////// Small Matrix ///////////////////////////
 //矩阵基本运算:加、减、缩放、乘、除、(矩阵)乘、转置

 struct CV_EXPORTS Matx_AddOp {};
 struct CV_EXPORTS Matx_SubOp {};
 struct CV_EXPORTS Matx_ScaleOp {};
 struct CV_EXPORTS Matx_MulOp {};
 struct CV_EXPORTS Matx_DivOp {};
 struct CV_EXPORTS Matx_MatMulOp {};
 struct CV_EXPORTS Matx_TOp {};

 template<typename _Tp, int m, int n>
 class Matx
 {
 public:
     //枚举类型实质上是整数的别名,这里结合模板技术在构建对象时,矩阵的维度是只读的变量;
     enum {
            rows     = m,               //行
            cols     = n,               //列
            channels = rows*cols,       //元素数量
            shortdim = (m < n ? m : n)  //维度较小的那个变量,用于矩阵的秩
          };
     //Matx 成员变量仅是一个mxn数组
     _Tp val[m*n]; //< matrix elements

     typedef _Tp                           value_type;
     typedef Matx<_Tp, m, n>               mat_type;
     typedef Matx<_Tp, shortdim, >        diag_type;

     // default constructor  构造函数
     // 直接使用参数列表目前最多16维度(16x1 or 4x4),再多考虑是否应该使用Mat类

     Matx()
     {
     ; i < channels; i++) val[i] = _Tp();
     }

     Matx(_Tp v0) //!< 1x1 matrix
     {
     val[] = v0;
     ; i < channels; i++) val[i] = _Tp();
     }
     Matx(_Tp v0, _Tp v1) //!< 1x2 or 2x1 matrix
     {
     CV_StaticAssert(channels >= , "Matx should have at least 2 elements.");
     val[] = v0; val[] = v1;
     ; i < channels; i++) val[i] = _Tp();
     }
     Matx(_Tp v0, _Tp v1, _Tp v2); //!< 1x3 or 3x1 matrix
     Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3); //!< 1x4, 2x2 or 4x1 matrix
     Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4); //!< 1x5 or 5x1 matrix
     Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5);
     Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6);
     Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7);
     Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7, _Tp v8);
     Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7, _Tp v8, _Tp v9);
     Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3,
          _Tp v4, _Tp v5, _Tp v6, _Tp v7,
          _Tp v8, _Tp v9, _Tp v10, _Tp v11); //!< 1x12, 2x6, 3x4, 4x3, 6x2 or 12x1 matrix
     Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3,
          _Tp v4, _Tp v5, _Tp v6, _Tp v7,
          _Tp v8, _Tp v9, _Tp v10, _Tp v11,
          _Tp v12, _Tp v13); //!< 1x14, 2x7, 7x2 or 14x1 matrix
     Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3,
          _Tp v4, _Tp v5, _Tp v6, _Tp v7,
          _Tp v8, _Tp v9, _Tp v10, _Tp v11,
          _Tp v12, _Tp v13, _Tp v14, _Tp v15); //!< 1x16, 4x4 or 16x1 matrix

     // C语言中的普通数组形式进行构造对象
     explicit Matx(const _Tp* vals); //!< initialize from a plain array
     // C11 初始化列表新特性
 #ifdef CV_CXX11
     Matx(std::initializer_list<_Tp>); //!< initialize from an initializer list
 #endif

     //静态类成员函数,用于生成特殊的矩阵,便于矩阵的运算操作
     static Matx all(_Tp alpha)   // 将矩阵中的所有元素全都替换成alpha数值
     {
         Matx<_Tp, m, n> M;
         ; i < m*n; i++ )
             M.val[i] = alpha;
         return M;
     }
     static Matx zeros()  // 生成固定大小的零矩阵,Matx<int, 3, 3> t; t.zeros();
     {
         );
     }

     static Matx ones()       // 生成固定大小的数据元素全是1的矩阵
     {
     );
     }
     static Matx eye()                      // 生成固定大小的单位矩阵
     {
     Matx<_Tp,m,n> M;
     ; i < shortdim; i++)
         M(i,i) = ;
     return M;
     }
     static Matx diag(const diag_type& d)   // 生成固定大小的对角阵
     {
         Matx<_Tp,m,n> M;
         ; i < shortdim; i++)
             M(i,i) = d(i, );
         return M;
     }
     static Matx randu(_Tp a, _Tp b);        // 随机阵但源码没有找到相关定义
     static Matx randn(_Tp a, _Tp b);        // 随机阵但源码没有找到相关定义

     //! dot product computed with the default precision
     //矩阵的点积运算
     _Tp dot(const Matx<_Tp, m, n>& M) const;
     {
         _Tp s = ;
         ; i < channels; i++ )
             s += val[i]*M.val[i];
         return s;
     }

     //! dot product computed in double-precision arithmetics
     double ddot(const Matx<_Tp, m, n>& M) const
     {
         ;
         ; i < channels; i++ )
             s += (double)val[i]*M.val[i];
         return s;
     }

     //! conversion to another data type
     // saturate_cast用于防止数据溢出,后续有专文讨论。
     template<typename T2> operator Matx<T2, m, n>()
     {
         Matx<T2, m, n> M;
         ; i < m*n; i++ )
             M.val[i] = saturate_cast<T2>(val[i]);
         return M;
     }

     //! change the matrix shape
     template<int m1, int n1> Matx<_Tp, m1, n1> reshape() const
     {
         CV_StaticAssert(m1*n1 == m*n, "Input and destnarion matrices must have the same number of elements");
         return (const Matx<_Tp, m1, n1>&)*this;
     }
     //! extract part of the matrix
     template<int m1, int n1> Matx<_Tp, m1, n1> get_minor(int i, int j) const
     {
         CV_DbgAssert( <= i && i+m1 <= m &&  <= j && j+n1 <= n);
         Matx<_Tp, m1, n1> s;
         ; di < m1; di++ )
             ; dj < n1; dj++ )
                 s(di, dj) = (*this)(i+di, j+dj);
         return s;
     }

     //! extract the matrix row
     Matx<_Tp, , n> row(int i) const
     {
     CV_DbgAssert((unsigned)i < (unsigned)m);
     , n>(&val[i*n]);
     }

     //! extract the matrix column
     Matx<_Tp, m, > col(int i) const
     {
     CV_DbgAssert((unsigned)j < (unsigned)n);
     Matx<_Tp, m, > v;
     ; i < m; i++ )
         v.val[i] = val[i*n + j];
     return v;
     }

     //! extract the matrix diagonal
     diag_type diag() const
     {
     diag_type d;
     ; i < shortdim; i++ )
         d.val[i] = val[i*n + i];
     return d;
     }
     //! transpose the matrix
     Matx<_Tp, n, m> t() const
     {
     return Matx<_Tp, n, m>(*this, Matx_TOp());
     }

     //! multiply two matrices element-wise
     Matx<_Tp, m, n> mul(const Matx<_Tp, m, n>& a) const
     {
         return Matx<_Tp, m, n>(*this, a, Matx_MulOp());
     }

     //! divide two matrices element-wise
     Matx<_Tp, m, n> div(const Matx<_Tp, m, n>& a) const
     {
     return Matx<_Tp, m, n>(*this, a, Matx_DivOp());
     }

     //! element access
     const _Tp& operator ()(int i, int j) const
     {
     CV_DbgAssert( (unsigned)i < (unsigned)m && (unsigned)j < (unsigned)n );
     return this->val[i*n + j];
     }

     _Tp& operator ()(int i, int j);
     {
     CV_DbgAssert( (unsigned)i < (unsigned)m && (unsigned)j < (unsigned)n );
     return val[i*n + j];
     }
     //! 1D element access
     const _Tp& operator ()(int i) const
     {
     CV_StaticAssert(m ==  || n == , "Single index indexation requires matrix to be a column or a row");
     CV_DbgAssert( (unsigned)i < (unsigned)(m+n-) );
     return val[i];
     }

     _Tp& operator ()(int i);
     {
     CV_StaticAssert(m ==  || n == , "Single index indexation requires matrix to be a column or a row");
     CV_DbgAssert( (unsigned)i < (unsigned)(m+n-) );
     return val[i];
     }

     //矩阵运算
     Matx(const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b, Matx_AddOp)
     {
         ; i < channels; i++ )
             val[i] = saturate_cast<_Tp>(a.val[i] + b.val[i]);
     }

     Matx(const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b, Matx_SubOp);
     {
     ; i < channels; i++ )
         val[i] = saturate_cast<_Tp>(a.val[i] - b.val[i]);
     }

     template<typename _T2> Matx(const Matx<_Tp, m, n>& a, _T2 alpha, Matx_ScaleOp)
     {
     ; i < channels; i++ )
         val[i] = saturate_cast<_Tp>(a.val[i] * alpha);
     }

     Matx(const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b, Matx_MulOp)
     {
     ; i < channels; i++ )
         val[i] = saturate_cast<_Tp>(a.val[i] * b.val[i]);
     }

     Matx(const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b, Matx_DivOp)
     {
     ; i < channels; i++ )
         val[i] = saturate_cast<_Tp>(a.val[i] / b.val[i]);
     }

     template<int l> Matx(const Matx<_Tp, m, l>& a, const Matx<_Tp, l, n>& b, Matx_MatMulOp)
     {
     ; i < m; i++ )
         ; j < n; j++ )
         {
             _Tp s = ;
             ; k < l; k++ )
                 s += a(i, k) * b(k, j);
             val[i*n + j] = s;
         }
     }
     Matx(const Matx<_Tp, n, m>& a, Matx_TOp)
     {
     ; i < m; i++ )
         ; j < n; j++ )
             val[i*n + j] = a(j, i);
     }

     //! invert the matrix  求逆
     Matx<_Tp, n, m> inv(int method=DECOMP_LU, bool *p_is_ok = NULL) const;

     //! solve linear system   求线性方程
     template<int l> Matx<_Tp, n, l> solve(const Matx<_Tp, m, l>& rhs, int flags=DECOMP_LU) const;
     Vec<_Tp, n> solve(const Vec<_Tp, m>& rhs, int method) const
     {
         Matx<_Tp, n, > x = solve((>&)(rhs), method);
         return (Vec<_Tp, n>&)(x);
     }

 };

 typedef Matx<, > Matx12f;
 typedef Matx<, > Matx12d;
 typedef Matx<, > Matx13f;
 typedef Matx<, > Matx13d;
 typedef Matx<, > Matx14f;
 typedef Matx<, > Matx14d;
 typedef Matx<, > Matx16f;
 typedef Matx<, > Matx16d;

 typedef Matx<, > Matx21f;
 typedef Matx<, > Matx21d;
 typedef Matx<, > Matx31f;
 typedef Matx<, > Matx31d;
 typedef Matx<, > Matx41f;
 typedef Matx<, > Matx41d;
 typedef Matx<, > Matx61f;
 typedef Matx<, > Matx61d;

 typedef Matx<, > Matx22f;
 typedef Matx<, > Matx22d;
 typedef Matx<, > Matx23f;
 typedef Matx<, > Matx23d;
 typedef Matx<, > Matx32f;
 typedef Matx<, > Matx32d;

 typedef Matx<, > Matx33f;
 typedef Matx<, > Matx33d;

 typedef Matx<, > Matx34f;
 typedef Matx<, > Matx34d;
 typedef Matx<, > Matx43f;
 typedef Matx<, > Matx43d;

 typedef Matx<, > Matx44f;
 typedef Matx<, > Matx44d;
 typedef Matx<, > Matx66f;
 typedef Matx<, > Matx66d;

 #endif // OPENCV_CORE_MATX_HPP

精解Mat类(一):基本数据类型-固定大小的 矩阵类(Matx) 向量类(Vector)的更多相关文章

  1. iOS设计模式 - (2)UML类间关系精解

    在正式讲设计模式之前, 介绍一下UML类图之间的关系还是非常有必要的, 由于一些教程, 书籍, 包含我之后的文章, 都会大量使用类图, 去描写叙述各个类之间的关系.这是一种非常直观, 简约的方式. 当 ...

  2. 【精解】EOS标准货币体系与源码实现分析

    EOS智能合约中包含一个exchange合约,它支持用户创建一笔交易,是任何两个基本货币类型之间的交易.这个合约的作用是跨不同币种(都是EOS上的标准货币类型)的,通过各自与EOS主链价值进行锚定,然 ...

  3. 【算法】C语言趣味程序设计编程百例精解

    C语言趣味程序设计编程百例精解 C/C++语言经典.实用.趣味程序设计编程百例精解(1)  https://wenku.baidu.com/view/b9f683c08bd63186bcebbc3c. ...

  4. 《React Native 精解与实战》书籍连载「iOS 平台与 React Native 混合开发」

    此文是我的出版书籍<React Native 精解与实战>连载分享,此书由机械工业出版社出版,书中详解了 React Native 框架底层原理.React Native 组件布局.组件与 ...

  5. 《React Native 精解与实战》书籍连载「Node.js 简介与 React Native 开发环境配置」

    此文是我的出版书籍<React Native 精解与实战>连载分享,此书由机械工业出版社出版,书中详解了 React Native 框架底层原理.React Native 组件布局.组件与 ...

  6. [转帖]算法精解:DAG有向无环图

    算法精解:DAG有向无环图 https://www.cnblogs.com/Evsward/p/dag.html DAG是公认的下一代区块链的标志.本文从算法基础去研究分析DAG算法,以及它是如何运用 ...

  7. Jackson精解第4篇-@JacksonInject与@JsonAlias注解

    Jackson是Spring Boot(SpringBoot)默认的JSON数据处理框架,但是其并不依赖于任何的Spring 库.有的小伙伴以为Jackson只能在Spring框架内使用,其实不是的, ...

  8. sed实例精解--例说sed完整版

    原文地址:sed实例精解--例说sed完整版 作者:xiaozhenggang 最近在学习shell,怕学了后面忘了前面的就把学习和实验的过程记录下来了.这里是关于sed的,前面有三四篇分开的,现在都 ...

  9. Storm流计算从入门到精通之技术篇(高并发策略、批处理事务、Trident精解、运维监控、企业场景)

    1.Storm全面.系统.深入讲解,采用最新的稳定版本Storm 0.9.0.1 :   2.注重实践,对较抽象难懂的技术点如Grouping策略.并发度及线程安全.批处理事务.DRPC.Storm ...

随机推荐

  1. GCD实现倒计时

    之前面试中,好多面试官,问使用GCD如何实现倒计时,我当时也没写过,所以一时不知道怎么说,所以结束之后,我实现一下GCD的倒计时. - (void)startTime:(UIButton *)send ...

  2. 软AP的实现------dhcpserver交叉编译

    代码版本:dhcp-4.2.5-P1 cd dhcp--P1; ./configure --host=arm-XXX-linux ac_cv_file__dev_random=yes; cd ./bi ...

  3. 安装VMware Workstation提示the msi failed的解决办法

    有朋友安装VMware Workstation时出现报错,提示the msi failed等信息,原来他以前安装过绿色版.优化版的VM,但删掉后重装VM就会有这样的报错提示,如果你也遇到了相同的困扰, ...

  4. QRCode 扫描二维码、扫描条形码、相册获取图片后识别、生成带 Logo 二维码、支持微博微信 QQ 二维码扫描样式

    目录 功能介绍 常见问题 效果图与示例 apk Gradle 依赖 布局文件 自定义属性说明 接口说明 关于我 功能介绍 根据之前公司的产品需求,参考 barcodescanner 改的,希望能帮助到 ...

  5. spring中自定义Event事件的使用和浅析

    在我目前接触的项目中,用到了许多spring相关的技术,框架层面的spring.spring mvc就不说了,细节上的功能也用了不少,如schedule定时任务.Filter过滤器. intercep ...

  6. vxWorks 命令

    1.4.1 任务管理    sp( )            用缺省参数创建一个任务(priority="100" 返回值为任务ID,或错误)(taskSpawn) sps( )  ...

  7. FusionCharts中图的属性的总结归纳

    FusionCharts中图的属性的总结归纳 1.横坐标label间隔显示 labelStep="4" 2.柱状图有椭圆角 useRoundEdges="1"

  8. Hello China操作系统在Virtual PC上的安装和使用

    http://blog.csdn.net/hellochina15/article/details/7253350 本文介绍如何在Windows 7操作系统和Virtual PC 2007虚拟机上安装 ...

  9. bzoj 4026 dC Loves Number Theory

    把我写吐了 太弱了 首先按照欧拉函数性质 我只需要统计区间不同质数个数就好了 一眼主席树 其次我被卡了分解质因数这里 可以通过质数筛时就建边解决 不够灵性啊,不知道如何改 #include<bi ...

  10. HTML基础加强

    1. 什么是浏览器:解释和执行HTML源码的工具. 2. 什么是静态页面,什么样的页面是动态页面? 静态页面:htm,html(直接读取) 动态网页:asp,aspx,jsp,php(里面有代码请求时 ...