天天看點

OpenCV3 第四章學習筆記-------Mat用法、多種格式化輸出方法、常用資料結果、基本繪圖操作

目錄

一、Mat結構的使用

1、OpenCV簡介 

 2、Mat類介紹 —圖像容器類&通用矩陣類

3、Mat類對象的七種建立方式

4、OpenCV對矩陣的輸出格式

5、OpenCV輸出其他常用資料結構

二、常用資料結構和函數

1、點:Point類

2、顔色:Scalar類

3、尺寸的表示:Size類

4、矩形的表示:Rect類

5、顔色空間轉換:cvtColor()函數

三、基本圖像的繪制

1、繪制常見的線型

2、繪制結果圖

一、Mat結構的使用

1、OpenCV簡介 

OpenCV是計算機視覺庫(圖像處理庫),主要工作是操作和處理一個包含衆多強度值的像素點矩陣。早期的OpenCV基于c接口建構的,那時利用IplImage的C語言結構體在記憶體中存儲圖像,要手動管理記憶體,如果退出前忘記釋放記憶體就會導緻記憶體洩漏,不利于大型程式開發。OpenCV在2.0之後采用了C++接口,利用C++類的概念,輕松實作自動管理記憶體。                                   

C++接口唯一的不足:目前嵌入式開發系統隻支援C語言,是以這種情況下要用c接口的。

 2、Mat類介紹 —圖像容器類&通用矩陣類

  • 不必手動為其開辟空間
  • 不必再在不需要時手動将空間釋放           
  • Mat是一個類,包括矩陣頭(包括矩陣尺寸、存儲方法、存儲位址等)和矩陣(存儲矩陣所有像素值,可以是不同維數的)
  • OpenCV作為圖像處理庫,内部含有多個圖像處理函數,常常在函數之間進行圖像傳遞,而圖像傳遞建立副本時由于矩陣有時很大會造成很大的開銷,為了解決這個問題,OpenCV中采用了
  • 計數機制—隻複制矩陣頭而不複制矩陣

即讓每個Mat對象都有自己的矩陣頭(資訊頭),但共享同一個矩陣(讓矩陣指針指向同一位址實作),拷貝函數隻拷貝矩陣頭而不複制矩陣,對任何一個對象的操作都會影響其他對象。因為這種通過拷貝函數生成的多個對象,矩陣是屬于多個對象的,當不再需要時,通過最後一個使用他的對象清除。

計數展現在:無論什麼時候複制矩陣頭,計數器都加一,反之,釋放資訊頭時,計數器減一,當計數器為0時,矩陣就被清除。

  • 函數clone()和copyTo()實作複制矩陣

3、Mat類對象的七種建立方式

#include "stdafx.h"
#include<iostream>
#include<windows.h>
using namespace std;
// 以下四句話作為OpenCV的标配
#include<opencv2/core/core.hpp>
#include<opencv2/highgui/highgui.hpp>
#include<opencv2/opencv.hpp>
using namespace cv;	//OpenCV中的C++類和函數都是定義在cv的命名空間


int main()
{
    // 三、建立Mat對象的其中方式
	// 3.1 使用Mat()構造函數:Mat M(行, 列, CV_[位數][帶符号與否][類型字首]C[通道數], 
    // Scalar(初始值清單));
    //2*2,每個像素灰階值用8位無符号char型表示(0~255),
    //每個像素是由三個元素組成的三通道。初始值為(0,3,255)
	Mat M(2, 2, CV_8UC3, Scalar(0, 3, 255));  
	cout << "M=" << endl << "" << M << endl << endl;//<<運算符隻對二維的有效
	

	// 3.2 C/C++中通過構造函數進行初始化
	int sz[3] = { 2,2,2 };
	Mat L(3, sz,CV_8UC3, Scalar::all(0));	//imshow("L", L);顯示錯誤

	/* // 3.3 為已存在的IplImage指針建立資訊頭
	/IplImage* img = cvLoadImageA("1.jpg", 1);
	Mat mtx(img);*/
	
	// 3.4 利用creat()函數,不能設定矩陣的初始值,且必須先定義對象(矩陣頭),再建立矩陣
	Mat C;
	C.create(4, 4, CV_8UC(3));// CV_8UC(a)—有a個4*4的矩陣放在一行
	cout << "C=" << endl << "" << C << endl << endl;//<<運算符隻對二維的有效
	
	
	// 3.5 采用Matlab式的初始化方式:ones(),zeros(),eyes()
	Mat E = Mat::eye(4, 4, CV_64F);
	cout << "3.5: E=" << endl << "" << E << endl << endl;

	Mat Z = Mat::zeros(4, 4, CV_64F);
	cout << "3.5: Z=" << endl << "" << Z << endl << endl;

	Mat O = Mat::ones(4, 4, CV_64F);
	cout << "3.5: O=" << endl << "" << O << endl << endl;

	// 3.6 對小矩陣使用逗号分隔式初始化函數

	Mat D = (Mat_<double>(3, 3) << 0, -1, 0, -1, 5, -1, 0, -1, 0);
	cout << "D = " << endl << "" << D << endl << endl;

	// 3.7 為已存在的對象建立新的資訊頭
	Mat RowClone = D.row(0).clone();
	cout << "RowClone = " << endl << "" << RowClone << endl << endl;
	Sleep(10 * 1000);//延時
	waitKey(10);
	return 0; // 按下ESC鍵,程式退出
}
           

4、OpenCV對矩陣的輸出格式

#include "stdafx.h"
#include<iostream>
#include<windows.h>
using namespace std;
// 以下四句話作為OpenCV的标配
#include<opencv2/core/core.hpp>
#include<opencv2/highgui/highgui.hpp>
#include<opencv2/opencv.hpp>
using namespace cv;	//OpenCV中的C++類和函數都是定義在cv的命名空間


int main()
{
// 四、OpenCV中格式化輸出方法
	// 4.0 産生一個矩陣,并用在一定範圍内的随機數填充矩陣
	Mat r = Mat(2, 3, CV_8UC3);
	randu(r, Scalar::all(0), Scalar::all(255));

	// 4.1 輸出格式一:OpenCV預設風格
	cout << "r(OpenCV預設風格)=:\n" << r << ";" << endl << endl;

	// 4.2 輸出格式一:Python預設風格
	//cout << "r(Python預設風格)=:\n" << format(r,"python") << ";" << endl << endl;//OpenCV2
	cout << "r(Python風格)=:\n" << format(r,Formatter::FMT_PYTHON) << ";" << endl << endl;//OpenCV3

	// 4.3 逗号分隔風格(Comma separated values,CSV)
	cout << "r(CSV風格)=:\n" << format(r, Formatter::FMT_CSV)<< ";" << endl << endl;//OpenCV3

	// 4.4 Numpy風格
	cout << "r(Numpy風格)=:\n" << format(r, Formatter::FMT_NUMPY) << ";" << endl << endl;//OpenCV3
	
	// 4.5 C語言
	cout << "r(C語言)=:\n" << format(r, Formatter::FMT_C) << ";" << endl << endl;//OpenCV3
	
	// 4.6 Matlab語言
	cout << "r(Matlab語言)=:\n" << format(r, Formatter::FMT_MATLAB) << ";" << endl << endl;//OpenCV3
	Sleep(20 * 1000);//延時
	waitKey(0);
	return 0; 
	
    
}

           
OpenCV3 第四章學習筆記-------Mat用法、多種格式化輸出方法、常用資料結果、基本繪圖操作

5、OpenCV輸出其他常用資料結構

OpenCV3 第四章學習筆記-------Mat用法、多種格式化輸出方法、常用資料結果、基本繪圖操作
OpenCV3 第四章學習筆記-------Mat用法、多種格式化輸出方法、常用資料結果、基本繪圖操作
// 五、輸出其他資料結構

	// 5.1 定義和輸出二維點
	Point2f p(6, 2); 
	cout << "【二維點】p=\n" << p << ";\n"<<endl;
	// 5.2 定義和輸出三維點
	Point3f p3f(8, 2, 0);
	cout << "【三維點】p3f=\n" << p3f << ";\n" << endl;
	// 5.3 定義和輸出基于Mat的std::vector
	vector<float> v;
	v.push_back(3);
	v.push_back(5);
	v.push_back(7);
	cout << "【基于Mat的vector】shortvec=\n" << Mat(v) << ";\n" << endl;

	// 5.4 定義和輸出基于Mat的std::vector
	vector<Point2f> points(10);
	for (size_t i = 0; i < points.size(); ++i)
		points[i] = Point2f((float)(i * 5), (float)(i % 7));

	cout << "【二維點向量】points=\n" << points << ";" ;
           

二、常用資料結構和函數

1、點:Point類

  • Point_<int>、Point2i、Point互相等價
  • Point_<float>、Point2f互相等價

2、顔色:Scalar類

  • Scalar()表示4個元素的數組,常用于傳遞像素值,如RGB值,如果隻寫3個參數,則認為值想表示三個參數
  • Scalar(a,b,c)如果定義RGB,則是按BGR的順序排列的
  • Scalar類的源頭是Scalar_類,Scalar_類是Vec4x的變種,常用的Scalar是Scalar_<double>,是以有些函數的參數輸入可以是Mat,也可以是Scalar。

3、尺寸的表示:Size類

  • 如下所示,Size_<int>、 Size2i、Size三者等價
typedef Size_<int> Size2i;
typedef Size2i Size;
           
  • Size(5,5);    // 構造出Size寬度和高度都為5(Size.width=5,Size.height=5)
               

4、矩形的表示:Rect類

  •  rect(x,y,width,height)    //左上點坐标,和矩形的寬和高
               
  • 可以用他的函數判斷一個點(矩形)是否在所給的矩形中或者傳回矩形的左上坐标、求兩個矩形的交集并集等等。

5、顔色空間轉換:cvtColor()函數

  • OpenCV存儲的RGB的順序是BGR

三、基本圖像的繪制

1、繪制常見的線型

  • 繪制直線:line
  • 繪制橢圓:ellipse
  • 繪制矩形:rectangle
  • 繪制圓:circle
  • 繪制填充多邊形:fillPoly

2、繪制結果圖

OpenCV3 第四章學習筆記-------Mat用法、多種格式化輸出方法、常用資料結果、基本繪圖操作

繼續閱讀