OpenCV中基本数据结构(7)_Vec
Vec系列数据结构是Matx的一个派生类,其矩阵的行的大小永远固定为一行,列大小从1到6不等,可以认为类似与C++ vector,但与C++ 的vector又有很大不同,,以下不同来自于一段技术博客,讲的比较清楚:OpenCV与C++ ...
Vec系列数据结构是Matx的一个派生类,其矩阵的行的大小永远固定为一行,列大小从1到6不等,可以认为类似与C++ vector,但与C++ 的vector又有很大不同,,以下不同来自于一段技术博客,讲的比较清楚:
| OpenCV与C++ STL中的向量类比对 | ||
| Item | OpenCV | C++ STL |
| 数据存储 |
栈 加快程序的运行效率(节省动态申请的时间) |
堆 动态申请内存 |
| 容器类型 |
1.固定大小向量类在编译期间就知道维度的向量且维度相对小 2.通常情况下仅用来装载C语言中原生的int或float基本类型 |
可以装载任何类型甚至包含自定义的类类型。 |
下面来自以《learning Opencv3》对vec与 STL vector的说明:
Why not just use STL classes? The key difference is that fixed vector classes are intended for small vectors whose dimensions are known at compile time, This allows for particularly efficient code to handle small common operations.
Vec 预定义
Vec的格式如下:
cv:;Vec{2,3,6,}{b,s,w,i,f,d}
{2,3,6}:为矩阵的列大小,行永远为1
{b,s,w,i,f,d}:为数据类型。b为uchar,s为short, w为ushort, i为int,f为float,d为double
提前预定义的有如下:
typedef Vec<uchar, 2> Vec2b;
typedef Vec<uchar, 3> Vec3b;
typedef Vec<uchar, 4> Vec4b;
typedef Vec<short, 2> Vec2s;
typedef Vec<short, 3> Vec3s;
typedef Vec<short, 4> Vec4s;
typedef Vec<ushort, 2> Vec2w;
typedef Vec<ushort, 3> Vec3w;
typedef Vec<ushort, 4> Vec4w;
typedef Vec<int, 2> Vec2i;
typedef Vec<int, 3> Vec3i;
typedef Vec<int, 4> Vec4i;
typedef Vec<int, 6> Vec6i;
typedef Vec<int, 8> Vec8i;
typedef Vec<float, 2> Vec2f;
typedef Vec<float, 3> Vec3f;
typedef Vec<float, 4> Vec4f;
typedef Vec<float, 6> Vec6f;
typedef Vec<double, 2> Vec2d;
typedef Vec<double, 3> Vec3d;
typedef Vec<double, 4> Vec4d;
typedef Vec<double, 6> Vec6d;
以上基本能够满足需求使用。
Vec类
Vec的类继承了Matx类,是一种特殊的矩阵,相当于Matx的行为1,由其定义就可以看出

Vec类方法总结如下:
| Method | Description |
| Vec | 默认构造函数 |
| Vec(_Tp v0) | 1-element构造函数 |
| Vec(_Tp v0, _Tp v1) | 2-element构造函数 |
| Vec(_Tp v0, _Tp v1, _Tp v2) | 3-element 构造函数 |
| Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3) | 4-element 构造函数 |
| Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4) | 5-element 构造函数 |
| Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5) | 6-element 构造函数 |
| Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6) | 7-element 构造函数 |
| Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7) | 8-element 构造函数 |
| Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7, _Tp v8) | 9-element 构造函数 |
| Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7, _Tp v8, _Tp v9) | 10-element 构造函数 |
| Vec(_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) | 14-element 构造函数 |
| Vec(const _Tp* values) | 数组初始化函数 |
| Vec(std::initializer_list<_Tp>) | list初始化函数 |
| Vec(const Vec<_Tp, cn>& v) | copy构造函数 |
| static Vec all(_Tp alpha) | 将所有的元素的值为 alpha |
| Vec mul(const Vec<_Tp, cn>& v) | 矩阵元素相乘 |
| Vec conj() | 矩阵共轭 |
| Vec cross(const Vec& v) | 矩阵叉乘 为两个三元素矩阵 |
| template<typename T2> operator Vec<T2, cn>() | 类型强转,转换成其他类型的vec |
| const _Tp& operator [](int i) | operator中的[]重构,能够像访问数组一样直接访问 |
| _Tp& operator[](int i) | operator中的[]重构,能够像访问数组一样直接访问 |
| onst _Tp& operator ()(int i) | operator中的()重构,能够直接使用()进行元素访问 |
| _Tp& operator ()(int i) | operator中的()重构,能够直接使用()进行元素访问 |
| Vec<_Tp, cn>& operator=(const Vec<_Tp, cn>& rhs) = default; | operator =重构 |
| Vec(const Matx<_Tp, cn, 1>& a, const Matx<_Tp, cn, 1>& b, Matx_AddOp) | 矩阵相加 |
| Vec(const Matx<_Tp, cn, 1>& a, const Matx<_Tp, cn, 1>& b, Matx_SubOp) | 矩阵相减 |
| template<typename _T2> Vec(const Matx<_Tp, cn, 1>& a, _T2 alpha, Matx_ScaleOp) | 矩阵缩放 |
下面例子列举出了几种创建初始化Vec的几种方法:
#include <stdio.h>
#include "opencv2/opencv.hpp"
using namespace cv;
using namespace std;
void main()
{
Vec3i v3i;
Vec3i v3i1(1, 2, 3);
int value[] = { 4,5,6 };
Vec3i v3i2(value);
cout << "v3i= " << v3i << endl;
cout << "v3i1= " << v3i1 << endl;
cout << "v3i2= " << v3i2 << endl;
Vec3i v3i3 = Vec3i::all(10);
cout << "v3i3= " << v3i3 << endl;
Vec3f v3i4;
for (int i = 0; i < v3i4.rows; i++)
{
v3i4[i] = i;
}
cout << "v3i4= " << v3i4 << endl;
Vec3i v3i5;
for (int i = 0; i < v3i5.rows; i++)
{
v3i5(i) = i+10;
}
cout << "v3i5= " << v3i5 << endl;
}
运行结果:

其他用例:
#include <stdio.h>
#include "opencv2/opencv.hpp"
using namespace cv;
using namespace std;
void main()
{
Vec3i v3i;
Vec3i v3i1(1, 2, 3);
Vec3i v3i2(4, 5, 6);
cout << "v3i1 = " << v3i1 << endl;
cout << "v3i2= " << v3i2 << endl;
cout << "v3i1.mul(v3i2)= " << v3i1.mul(v3i2) << endl;
cout << "v3i1.cross(v3i2)= " << v3i1.cross(v3i2) << endl;
}
运行结果:

Vec operator
由于Vec是继承了Matx类,所以Matx类的operator也同样做了继承,支持的operato和Matx一样,支持的主要如下:
All the expected vector operations are also implemented:
- v1 = v2 + v3
- v1 = v2 - v3
- v1 = v2 \* scale
- v1 = scale \* v2
- v1 = -v2
- v1 += v2 and other augmenting operations
- v1 == v2, v1 != v2
- norm(v1) (euclidean norm)
用例:
#include <stdio.h>
#include "opencv2/opencv.hpp"
using namespace cv;
using namespace std;
void main()
{
Vec3i v3i;
Vec3i v3i1(1, 2, 3);
Vec3i v3i2(4, 5, 6);
cout << "v3i1 = " << v3i1 << endl;
cout << "v3i2= " << v3i2 << endl;
cout << "v3i1+ v3i2= " << (v3i1 + v3i2) << endl;
cout << "v3i1- v3i2= " << (v3i1 - v3i2) << endl;
cout << "v3i1*2 = " << v3i1*2 << endl;
cout << "v3i1/2 = " << v3i1 / 2 << endl;
cout << "2* v3i1 = " << 2* v3i1 << endl;
cout << "-v3i1 = " << (-v3i1) << endl;
cout << "v3i1 == v3i2: " << (v3i1 == v3i2) << endl;
cout << "v3i1 != v3i2: " << (v3i1 != v3i2) << endl;
v3i1 += v3i2;
cout << "v3i1 += v3i2: " << v3i1 << endl;
}
运行结果:

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。
更多推荐


所有评论(0)