1. 程式人生 > >第四章 OpenCv的資料型別

第四章 OpenCv的資料型別

第四章 OpenCv的資料型別

1 直接從C++繼承來的基礎資料型別

本質:這類資料型別直接從C++原語中繼承而來,僅僅是稍加修飾,如int、float、及簡單陣列和矩陣,同時也有一些代表簡單幾何概念的資料型別,如點、矩形、大小等。
OpenCv中6種基本資料型別縮寫:
b = unsigned char
w = unsigned short
s = short
i = int
f = float
d = double

  • cv::Vec<>類

本質:固定向量容器,即定義時必須制定其大小,通過下標i訪問。
用法:對於2到6維的6種資料型別的任何組合都是有效的。雖然Vec<>可以包含其他類物件,但是opencv中一般只用作一個C語言原語的型別的容器。且僅用於少數量的元素。
Opencv中的常用別名:

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;
  • cv::Matx<>類

本質:固定矩陣類,通過下標(i,j)訪問。
用法:用於一些特定的小型固定矩陣,支援矩陣的操作。
Opencv中的常用別名

typedef Matx<float, 1, 2> Matx12f;
typedef Matx<double, 1, 2> Matx12d;
typedef Matx<float, 1, 3> Matx13f;
typedef Matx<double, 1, 3> Matx13d;
typedef Matx<float, 1, 4> Matx14f;
typedef Matx<double, 1, 4> Matx14d;
typedef Matx<float, 1, 6> Matx16f;
typedef Matx<double, 1, 6> Matx16d;

typedef Matx<float, 2, 1> Matx21f;
typedef Matx<double, 2, 1> Matx21d;
typedef Matx<float, 3, 1> Matx31f;
typedef Matx<double, 3, 1> Matx31d;
typedef Matx<float, 4, 1> Matx41f;
typedef Matx<double, 4, 1> Matx41d;
typedef Matx<float, 6, 1> Matx61f;
typedef Matx<double, 6, 1> Matx61d;

typedef Matx<float, 2, 2> Matx22f;
typedef Matx<double, 2, 2> Matx22d;
typedef Matx<float, 2, 3> Matx23f;
typedef Matx<double, 2, 3> Matx23d;
typedef Matx<float, 3, 2> Matx32f;
typedef Matx<double, 3, 2> Matx32d;

typedef Matx<float, 3, 3> Matx33f;
typedef Matx<double, 3, 3> Matx33d;

typedef Matx<float, 3, 4> Matx34f;
typedef Matx<double, 3, 4> Matx34d;
typedef Matx<float, 4, 3> Matx43f;
typedef Matx<double, 4, 3> Matx43d;

typedef Matx<float, 4, 4> Matx44f;
typedef Matx<double, 4, 4> Matx44d;
typedef Matx<float, 6, 6> Matx66f;
typedef Matx<double, 6, 6> Matx66d;
  • cv::Point類

本質:類似於固定向量類,但僅用來表示一個點。
用法:一般用來表示二維點或者三維點,通過成員變數訪問元素,而不是下標。
Opencv中的常用別名

typedef Point_<int> Point2i;
typedef Point_<int64> Point2l;
typedef Point_<float> Point2f;
typedef Point_<double> Point2d;
typedef Point3_<int> Point3i;
typedef Point3_<float> Point3f;
typedef Point3_<double> Point3d;
  • cv::Scalar類

本質:一個四維Point類。通過下標訪問訪問。

  • cv::Size類

本質:與point類似,表示區域的大小,擁有width和height。
Opencv中的常用別名

typedef Size_<int> Size2i;
typedef Size_<int64> Size2l;
typedef Size_<float> Size2f;
typedef Size_<double> Size2d;
typedef Size2i Size;
  • cv::Rect類

本質:顧名思義,表示一個矩形。
非對稱矩形:cv::RotateRect。

  • cv::Complex類

本質:複數類,實部通過re獲取,虛部通過im獲取。
Opencv中的常用別名

typedef Complex<float> Complexf;
typedef Complex<double> Complexd;

2 輔助物件型別

  • cv::TermCriteria類

本質:一個終止條件檢測類。集成了迭代次數和誤差引數。

  • cv::Range類

本質:一個連續的整數序列,兩個重要元素start和end。範圍包含初始值start但不包含終止值end。

  • cv::ptr智慧指標

本質:與C++只能指標類似。

  • cv::InputArray和cv::OutputArray類

本質:陣列的封裝,可以表示任何陣列,常用於函式的傳人蔘數和返回引數。前者為常量陣列。

3 工具函式

函式名稱 描述
Cv::alignPtr() 對齊指標到給點位元組數
Cv::alignSize() 將緩衝區大小與給定的位元組數對齊
Cv::allocate() 分配一個C風格的陣列物件
cvCeil() 浮點數向上取整
Cv::cubeRoot() 計算一個數的立方根
Cv::CV_Assert() 如果給定的條件不為真,則丟擲異常
CV_Error() 構造cv::Exception(從固定的字串)並丟擲異常的一個巨集
CV_Error_() 構造cv::Exception(從格式化字串)並丟擲異常的一個巨集
Cv::deallocate() 釋放一個c風格的陣列物件
Cv::error() 指示錯誤並丟擲異常
Cv::fastAtan2() 向量的二維角度的計算
Cv::fastFree() 釋放一個記憶體快取區
Cv::fastMalloc() 分配一個對齊的記憶體快取區
cvFloor() 浮點數向下取整
Cv::format() 以sprintf類似格式建立一個STL字串
Cv::getCPUTickCount() 以內部CPU計時器獲得tick計數
Cv::getNumThreads() 獲得當前OpenCv使用的執行緒數
Cv::getOptimalDFTSize() 計算要傳遞給cv::DFT()的陣列的最適合大小
Cv::getThreadNum() 獲得當前執行緒的索引
Cv::getTickFrequency () 獲得系統每秒的tick計數
Cv::getTickCount() 獲得系統的tick計數
cvIsInf() 判斷一個浮點數是否無窮
cvIsNaN() 判斷一個浮點數是否不是一個數
cvRound() 近似一個浮點數到最近整數
Cv::setNumThreads() 設定OpenCv使用的執行緒數
Cv::setUseOptimized() 開啟或關閉優化程式碼
Cv:useOptimized() 指示程式碼優化的啟用

4 影象和大型陣列型別

Cv::Mat類用於表示任意維度的稠密陣列。
稠密:表示該陣列的所有部分都有一個值儲存,即使這個值是0。
稀疏:表示只有非0的陣列會被儲存。
Mat理解:它僅僅是資料實體的頭,是對資料的描述,並不代表實際資料本身。

4.1 Mat的構造

Mat的非複製建構函式

Mat(int rows, int cols, int type);
指定型別的二維陣列,type取值為:CV_{8U,16S,16U,32S,32F,64F}C{1,2,3}的多種組合。

Mat(int rows, int cols, int type, void* data, size_t step=AUTO_STEP);
指定型別的二維陣列,並指定預先儲存的資料。

Mat(Size size, int type);
指定型別的二維陣列,大小由Sz指定。

Mat(int rows, int cols, int type, const Scalar& s);
指定型別的二維陣列,並指定初始化值。

Mat(Size size, int type, void* data, size_t step=AUTO_STEP);
指定型別的二維陣列,並指定預先儲存的資料。

Mat(int ndims, const int* sizes, int type);
指定型別的多維陣列。

Mat(int ndims, const int* sizes, int type, const Scalar& s);
指定型別的多維陣列,並指定初始化值。

Mat(int ndims, const int* sizes, int type, void* data, const size_t* steps=0);
指定型別的多維陣列,並指定預先儲存的資料。

Mat的複製建構函式

Mat(const Mat& m);
Mat(const Mat& m, const Range& rowRange, const Range& colRange=Range::all());
只從指定的行列中複製資料的複製建構函式。

Mat(const Mat& m, const Rect& roi);
只從感興趣的區域中複製資料的複製建構函式。
Mat(const Mat& m, const Range* ranges);
服務於n維陣列的,從泛化的感興趣區域中複製資料的複製建構函式。
構造Mat的靜態方法
static MatExpr zeros(int rows, int cols, int type);
構造指定大小的0矩陣。
static MatExpr ones(int rows, int cols, int type);
構造指定大小的全1矩陣。
static MatExpr eyes(int rows, int cols, int type);
構造指定大小的單位矩陣。

4.2 Mat獨立獲取陣列元素

Mat訪問一個元素主要有兩種方法:位置和迭代器。

4.2.1 位置訪問

直接訪問通過模板函式at<>()來實現。
本質:先將at<>()特化到矩陣所包含的資料型別,然後使用得到的資料型別的行和列位置訪問該元素。
通過位置訪問元素最快的方式:獲取某一行的指標。
mtx.ptr(3) 獲取指向第三行第一個元素的指標。
注意:Mat中的資料按行組織的,行於行之間有可能是連續的,可有使用isContinuous()進行判斷。
示例:

Mat type(2, 2, CV_8UC3);
type.at<Vec3b>(0, 1)[0] = 1;
type.at<Vec3b>(0, 1)[1] = 2;
type.at<Vec3b>(0, 1)[2] = 3;
std::cout << type;

// 取得某一行的指標
Ptr<Vec3b> p = type.ptr<Vec3b>(0);
p[1][0] = 4;
p[1][1] = 5;
p[1][2] = 6;

std::cout << std::endl;
std::cout << type;

4.2.2 迭代器訪問

Mat I(2, 2, CV_8UC3);
MatIterator_<Vec3b> it, end;
for (it = I.begin<Vec3b>(), end = I.end<Vec3b>(); it != end; ++it)
{
	(*it)[0] = 1;
	(*it)[1] = 2;
	(*it)[2] = 3;
}

4.3 通過塊訪問陣列元素

通過制定行、制定列、制定行範圍、制定列範圍、制定Range範圍來獲得制定的塊元素。返回值同樣是Mat。

4.4 Mat其他重要的函式成員

m1 = m0.clone() 從m0進行完全複製
m0.copyTo(m1) 將m0複製給m
m0.convertTo(m1, type, scale,offset) 轉換m0中的資料元素
m0.setTo(s, mask) 設定m0所有元素為s,如果存在mask,則只對制定區域置值
m0.total() 計算陣列元素數量(不包含通道)
m0.isContinuous() 判斷陣列是否連續
m0.type() 返回m0元素的型別
m0.depth() 返回m0通道中的元素型別
m0.channels() 返回m0的通道數目
m0.size() size返回m0的大小

5 總結

本章主要介紹了OPenCv中的一些基本資料型別和其使用方法,重點介紹了核心資料型別Mat,同時還介紹了一些常用的工具函式。