Opencv学习笔记五:了解opencv的数据类型

前言

在学习opencv的过程中我体验到,打好基础很重要,而了解opencv的数据类型就是打基础的一步,不了解透彻opencv的数据类型,在后期写代码,哪怕是抄代码都会是云里雾里。
本篇博文是我看《学习oepncv3》这本书第三章"了解opencv的数据类型"后所写。
opencv的数据类型大体有三类:

  1. 直接从C++中继承的基础类型(如int和float等)。这些类型包括简单的数组和矩阵,同时也代表了一些简单的几何概念,比如点,矩阵,大小等。
  2. 第二类是辅助对象,这些对象代表更抽象的概念,比如垃圾收集指针类,用于数据切片的范围对象(ranges objiects)以及抽象的终止条件类等。不过我对于此类对象并不咋了解。也没遇见过。。这是第一次看见这些名词haha
  3. 第三类可以称为大型数据类型。典型代表就是cv::Mat类。这也是我们后面处理图像最常用到的数据类型

除了上面的三类,opencv还用到了很多标准模板库类(STL),我对这个也懂,但想来他应该是包含vector模板类的总称。可以看看其他CSDN博主是咋介绍STL的。https://blog.csdn.net/qq_40194498/article/details/79148874

基础类型概述

下面我们就总结一下oepncv大体上都有哪些特有的数据类型。虽然现在啥类型都没说,但先在这儿概述一下是有利于理清框架的,否则后面一定会懵逼了,《学习oepncv3》的作者应该也是这么想的。

固定向量类cv::Vec<>

固定向量类,故名思意,就是大小(维度)已知的小型向量,大小已知,就非常利于我们处理于此有管关的操作(比如清理与保存)。
但是,我们一般在程序里很少见到cv::Vec<>这种这种写法,更常见的是他的别名,比如cv::Vec2i,cv::Vec3i,cv::Vec4d这种名称(分别对应 2个元素的整型向量,3个元素的整型向量,4的元素的双浮点向量),如果你仔细看一下,就会看出他的命名是很有规律的。
有着cv::Vec{2,3,4,6}{b,w,s,i,f,d}形式的声明,对于2到6个维度的6种数据类型的任何组合都是有效的。

固定矩阵类cv::Matx<>

cv::Matx<>设计用于一些特定的小型矩阵的操作,如cv::Vec<>一样,cv::Matx<>一般也都以别名cv::Matx{1,2,3,4,6}{1,2,3,4,6}{f,d}的形式应用。

点cv::Point类

cv::Point是两到三个原语类型的容器。可以表示二维或三位的点座标。
cv::Point类是通过它们的成员是通过名称变量来访问的(mypoint.x,mypoint.y等),而不是通过下标访问(mypoint[0])。
如cv::Vec<>一样,Point类通过别名调用作为一个正确模板的实例。如cv::Point2i,cv::Point2f,cv::Point2d,cv::Point3i,cv::Point3f,cv::Point3d

颜色cv::Scalar类

Scalar类本质上是一个四维Point类,但我们后面会发现,它常常用来表示颜色,因此叫他颜色Scalar类,它的四维分别为R,G,B以及透明度或者H,S,V以及透明度。该类对象的元素是通过整数下标访问的。

cv::Size和cv::Rect类

与Point类相似,这两个类继承自自己的模板,他们的区别在于cv::Size有width和height两个属性而不是x,y。儿cv::Rect包含了这四个。

深入了解基础类型

Point类

Point类比较简单,他的函数列表也比较短,在此也不过多介绍了。
在这里插入图片描述

cv::Scalar类

在这里插入图片描述

Size类

size类在实际操作中与Point类是类似的,而且可以与Point类相互转换,这两者之间主要的差别在于Point类的数据成员是x,y;而Size类中对应的成员是weidth,heigth;
size类的三个别名分别cv::Size,cv::Size2i,cv::Size2f;前面两个是等价的,表示整数大小,最后面一个表示32位浮点型大小。
在这里插入图片描述

cv::Rect矩阵类

矩阵类包含Point类的成员函数X,Y(矩形左上角)和Size类的成员width和height(代表了矩阵的大小)。
在这里插入图片描述
cv::Rect也支持一系列的覆写操作符,它们可以用于计算两个矩形,一个矩形或别的对象的各种各样的几何特征。
在这里插入图片描述

固定矩阵类

固定矩阵类是为编译时就已知维度的矩阵打造的,这也是它成为固定的原因。因为它们内部的所有数据都是在堆栈上分配的,所以它们的分配和清除都很快。对固定矩阵类的操作运行很快,而且它们还在小型矩阵(22,33,等等)上做过特别的优化。
独立固定矩阵一般通过别名分配,cv::Matx{1,2,3,4,6}{1,2,3,4,6}{f,d}
因为固定向量矩阵支持的操作很多,这里先只列出几个常遇见的。
在这里插入图片描述

固定向量类

固定向量类是由固定矩阵类派生而来的。它们其实是为了跟方便的使用cv::Matx<>。有cv::Vec{2,3,4,6}{b,w,s,i,f,d}形式的声明
在这里插入图片描述

辅助对象

除了基本类型和大容器,还有一系列的辅助函数,它们对控制各式各样的算法(比如终止条件)和各种在容器上的操作(比如ranges后者slices)非常有用。这里我们只写一个cv::Range类。
cv::Range类用于确定一个连续的整数序列。cv::Range对象有两个元素start和end,它们经常在构造函数 cv::Range(int start, int end)中设定,范围包含初始值start,但不包含终止值end。

  • 使用size()函数可以得到一个range类的元素数量 range.size() ;
  • empty()函数用于检测一个range类是否含有元素。
  • range.all()可以在任何需要获得对象可用范围时使用

功能函数

功能函数包含数学操作,测试,错误生成,内存与线程处理,优化及其他工具。这里罗列一下几个:

  1. cv::getNumThreads() 获得当前Opencv使用的线程数
  2. cv::getThreadNum() 获得当前线程的索引
  3. cv::setNumThreads() 设定Opencv使用的线程数
  4. cv::getTickCount() 获得系统的tick数
  5. cvRound() 近似一个浮点数x到最近的整数

对于4. cv::getTickCount() 这个函数,我们可以用它来测算我们程序的运行时间,大体思路为:

  1. t = (double)cv::getTickCount(); 在程序开头进行读取当前系统的tick数,作为起始点
  2. t = ((double)cv::getTickCount() - t) / cv::getTickFrequency(); 在程序末尾计算经过的时间, // getTickcount函数:返回从操作系统启动到当前所经过的毫秒
    // getTickFrequency函数:返回每秒的计时周期数
    我们可以写一个计算摄像头的帧率的小程序:
#include "pch.h"
#include <iostream>
#include <opencv2/opencv.hpp>

using namespace cv;
using namespace std;

int main()
{
	Mat frame;
	VideoCapture capture(0);  //定义一个视频流对象
	double fps;
	char string[10];
	namedWindow("Camera FPS");
	double t = 0;
	while (1)
	{
		t = (double)getTickCount();
		if (waitKey(1) == 1)break;
		if (capture.isOpened())
		{
			capture >> frame;
			t = t = ((double)cv::getTickCount() - t) / cv::getTickFrequency();
			fps = 1.0 / t;
			sprintf_s(string, "%.2f", fps);      // 帧率保留两位小数
			//spintf函数容易望文生义,误以为是一个打印函数。实质上是一个字符串格式化命令。
			//主要功能是把格式化的数据写入某个字符串中,至于需要打印的话,还是得需要打印函数来对其进行打印。
			std::string fpsString("FPS:");
			fpsString += string;                    // 在"FPS:"后加入帧率数值字符串

			cout << fpsString << endl;
			cv::putText(frame, // 图像矩阵
				fpsString,                  // string型文字内容
				cv::Point(5, 20),           // 文字座标,以左下角为原点
				cv::FONT_HERSHEY_SIMPLEX,   // 字体类型
				0.5, // 字体大小
				cv::Scalar(0, 0, 0));       // 字体颜色
			imshow("Camera FPS", frame);
		}
		else
		{
			cout << "NO Camera Input! " << endl;
			break;
		}
	}
}

在这里插入图片描述
关于这个小程序有不理解的地方可以去这三篇博文看看。我是从这三篇搬运的。///
https://blog.csdn.net/jacke121/article/details/55045618
https://blog.csdn.net/wearlee/article/details/79693582
https://blog.csdn.net/sgc_bf/article/details/85796206


好了,正文到此就结束了,有问题欢迎评论区交流~!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章