OpenCV 笔记(09)— 常用的数据结构和函数(Vec、Point、Scalar、Size、Rect、cvtColor)

1. Vec 对象类型

Vec 是一个主要用于数值向量的模板类。我们可以定义向量的类型和组件的数量:

Vec<double, 19> myVector

我们还可以使用任何的预定义类型:

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<int, 2> Vec2i;
typedef Vec<int, 3> Vec3i;
typedef Vec<int, 4> Vec4i;

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;

实现了以下所有向量操作:

v1 = v2 + v3
v1 = v2 - v3
v1 = v2 * scale
v1 = scale * v2
v1 = -v2
v1 += v2
v1 == v2
v1 != v2

2. 点的表示 Point 类

Point 类数据结构表示了二维坐标系下的点,即由其图像坐标 xy 指定的 2D 点。用法如下:

Point point;
point.x = 10;
point.y = 8;

或者

Point point = Point(10, 8 );

另外, 与 Vec 类一样, OpenCV 为方便起见定义了以下 Point 别名:

typedef Point_<int> Point2i;
typedef Point2i Point;
typedef Point_<float> Point2f;
typedef Point_<double> Point2d;

所以, Point_<int>Point2iPoint 互相等价,Point_<float>Point2f 互相等价。

同样的,就像 Point 一样, Point3 模板类用于指定 3D 点。

OpenCVPoint 定义了以下运算符:

pt1 = pt2 + pt3;
pt1 = pt2 - pt3;
pt1 = pt2 * a;
pt1 = a * pt2;
pt1 = pt2 / a;
pt1 += pt2;
pt1 -= pt2;
pt1 *= pt2;
pt1 /= pt2;
double value = norm(pt);
pt1 == pt2;
pt1 != pt2;

3. 颜色的表示 Scalar 类

Scalar 对象类型是从 Vec 派生的模板类,有四个元素。

Scalar 表示具有 4 个元素的数组,在 OpenCV 中被大量用于传递和读取像素值,如 RGB 颜色值。而 RGB 颜色值为三个参数,其实对于 Scalar 函数来说, 如果用不到第四个参数, 则不需要写出来;若只写三个参数, OpenCV 会认为我们就想表示三个参数。

来看个例子。如果给出以下颜色参数表达式:

Scalar(b, g, r)
  • b 表示蓝色
  • g 表示绿色
  • r 表示红色

Scalar 类的源头为 Scalar_ 类,而 Scalar_ 类是 Vec4x 的一个变种,我们常用的 Scalar 其实就是 Scalar_<double> 。这就解释了为什么很多函数的参数输入可以是 Mat ,也可以是 Scalar

要访问 VecScalar 值,可以使用 [] 运算符,其初始化可以用传值的方式通过设置另一个标量、向量或值来完成,如下例所示:

Scalar s0(0);
Scalar s1(0.0, 1.0, 2.0, 3.0);
Scalar s2(s1);

4. 尺寸的表示 Size 类

OpenCV 中对 Size 类源代码有以下定义,用于指定图像或矩形大小。这个类添加了两个成员 widthheight ,以及有用的 area() 函数。

typedef Size_<int> Size2i;
typedef Size2i Size;

其中, Size_ 是个模板类,在这里 Size_<int> 表示其类体内部的模板所代表的类型为 int 。那这两句代码的意思,就是首先给已知的数据类型 Size_<int> 起个新名字, 叫 Size2i 。然后又给已知的数据类型 Size2i 起个新名字,叫 Size 。所以,连起来就是, Size_<int>Size2iSize 这三个类型名等价。

我们可以用 X.widthX.height 来分别表示其宽度和高度。

	Size s = Size(3, 4);
	cout << "s.width is " << s.width << endl;	// s.width is 3
	cout << "s.height is " << s.height << endl;	// s.height is 4

area 用法:

	Size s(10, 10);
	Mat img = Mat::zeros(s, CV_8UC1);
	s.width = 20;
	int area = s.area();
	cout << "area is " << area << endl;	// area is 200

5. 矩形的表示 Rect 类

Rect 类的成员变量有 xywidthheight , 分别为左上角点的坐标和矩形的宽和高。常用的成员函数有:

  • Size() 返回值为 Size
  • area() 返回矩形的面积;
  • contains(Point) 判断点是否在矩形内;
  • inside(Rect) 函数判断矩形是否在该矩形内;
  • tl() 返回左上角点坐标;
  • br() 返回右下角点坐标。

值得注意的是,如果想求两个矩形的交集和并集, 可以用如下格式:

Rect rect = recti & rect 2;
Rect rect = recti | rect 2;

如果想让矩形进行平移操作和缩放操作, 甚至可以这样写:

Rect rectShift = rect + point;
Rect rectScale = rect + size;

Rect 模板类可用于定义图像的感兴趣区域( Region of Interest ,简称 ROI ),如下所示:

	Mat img = imread("demo.jpg");
	Rect r(0, 0, 100, 100);
	Mat img_roi = img(r);

6. 颜色空间转换 cvtColor 函数

cvtColor() 函数是 OpenCV 里的颜色空间转换函数, 可以实现 RGB 颜色向HSVHSI 等颜色空间的转换,也可以转换为灰度图像。原型如下:

void cvtColor(InputArray src, OutputArray dst, int code, int dstCn=0)

第一个参数为输入图像,第二个参数为输出图像,第三个参数为颜色空间转换的标识符,第四个参数为目标图像的通道数,若该参数是 0,表示目标图像取源图像的通道数。下面是一个调用示例:

/ /此句代码的 OpenCV2 版为:
cvtColor(srclmage, dstImage, CV_GRAY2BGR) ; // 转换原始图为灰度图
/ /此句代码的 OpenCV3 版为:
cvtColor(srclmage, dstlmage, C0L0R_GRAY2BGR) ; // 转换原始图为灰度图

即对于颜色空间转换, OpenCV2CV_ 前缀的宏命名规范,被 OpenCV3COLOR_ 式的宏命名前缀所取代。另外,在这里需要再次提醒大家的是, OpenCV 默认的图片通道存储顺序是 BGR , 即蓝绿红,而不是 RGB

7. 其它常用知识点

  • Matx 是个轻量级的 Mat ,必须在使用前规定好大小,比如一个 2*3 的 float 型的 Matx , 可以声明为 Matx23f
  • VecMatx 的一个派生类,是一个一维的 Matx ,跟 vector 很相似。在 OpenCV 源码中有如下定义。
template<typename_Tp, int n> class Vec : public Matx<_Tp, n, 1> { ... };
typedef Vec<uchar, 2> Vec2b;
  • Range 类其实就是为了使 OpenCV 的使用更像 MATLAB 而产生的。比如 Range::all() 其实就是 MATLAB 里的符号。而 Range(a,b) 其实就是 MATLAB 中的 a:b ,注意这里的 a 和 b 都应为整型。
  • OpenCV 中防止内存溢出的函数有 alignPtralignSizeallocatedeallocatefastMallocfastFree 等。
  • <math.h> 里的一些函数使用起来很方便:
  1. 有计算向量角度的函数 fastAtan2
  2. 计算立方根的函数 cubeRoot
  3. 向上取整函数 cvCeil
  4. 向下取整函数 cvFloor
  5. 四舍五入函数 cvRound 等。

还有一些类似 MATLAB 里面的函数,比如 cvlslnf 判断自变量是否无穷大, cvIsNaN 判断自变量是否不是一个数。

  • 显示文字相关的函数有 getTextSizecvInitFontputText
  • 作图相关的函数有 circleclipLineellipseellipse2Polylinerectanglepolylines 、类 Linelterator
  • 填充相关的函数有 fillConvexPolyfillPoly
  • OpenCVRNG() 函数的作用为初始化随机数状态的生成器。
  • 3
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值