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


好了,正文到此就結束了,有問題歡迎評論區交流~!

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