日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

《OpenCV3编程入门》学习笔记4 OpenCV数据结构与基本绘图

發布時間:2023/11/27 生活经验 41 豆豆
生活随笔 收集整理的這篇文章主要介紹了 《OpenCV3编程入门》学习笔记4 OpenCV数据结构与基本绘图 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

第4章 OpenCV數據結構與基本繪圖

4.1 基礎圖像容器Mat

4.1.1 數字圖像存儲概述

??圖像在數碼設備中的表現形式:像素點矩陣

4.1.2 Mat結構的使用

1.OpenCV1.x時代
??基于C語言接口而建的圖像存儲格式IplImage*
??缺點:退出時忘記relese掉的話,會造成內存泄漏,手動釋放內存耗費時間
2.C++出現后
??自動的內存管理
??不足:許多嵌入式開發系統只支持C語言
3.OpenCV2.0時代
??Mat類數據結構
??優點:不必手動開辟空間、不必再在不需要時立即釋放空間
4.Mat類數據部分組成
(1)矩陣頭:矩陣尺寸、存儲方法、存儲地址等
(2)指向存儲所有像素值的矩陣的指針
5.計數機制
??矩陣本身尺寸數量級很大,傳遞圖像時造成比較大的開銷,為解決此問題,引入計數機制。
??計數機制:讓每個Mat對象有自己的信息頭,但共享同一個矩陣。通過讓矩陣指針指向同一個地址而實現,拷貝構造函數則只復制信息頭和矩陣指針,而不復制矩陣。這時,通過任何一個對象所做的改變會影響其他圖像。
(1)創建信息頭:

Mat A,C; //僅創建信息頭
Mat D(A,Rect(10,10,100,100)); //使用矩形界定信息頭
Mat E=A(Range:all(),Range(1,3)); //用行和列界定信息頭

(2)矩陣清理:復制一個信息頭會增加矩陣的引用次數,反之,當一個頭被釋放后,計數會減一,當計數值為0,矩陣會被清理。
(3)復制矩陣本身函數:clone()或copyTo(),改變一個對象不會影響其他對象,例如:

Mat F=A.clone();
Mat G;
A.copyTo(G);

4.1.3 像素值的存儲方法

1.存儲像素值需要指定顏色空間和數據類型,顏色空間
(1)灰度級空間:黑白組合
(2)其他顏色空間:
??1)RGB顏色空間最常用;
??2)HSV和HLS把顏色分解成色調、飽和度和亮度/明度,拋棄最后一個元素算法對輸入圖像的光照條件不敏感
??3)YCrCb在JPEG圖像格式中廣泛使用
??4)CIE L*a*b*是一種在感知上均勻的顏色空間,它適合用來度量兩個顏色之間的距離
2.每個組成元素都有自己的定義域,定義域取決于其數據類型
(1)char:最小數據類型,1字節(8位),RGB顏色空間使用三個char,可表示1600萬種
(2)有符號型:0到255
(3)無符號型:-127到+127
(4)float或double:能給出更加精細的顏色分辨能力

4.1.4 顯式創建Mat對象的7種方法

??(Mat不但是圖像容器類,也是通用矩陣類,可以用來創建多維矩陣)

1.Mat()構造函數
??二維多通道圖像定義:行數,列數,存儲元素數據類型和矩陣點通道數(CV_[位數][帶符號與否][類型前綴]C[通道數]),定制化值初始化矩陣,如:

Mat M(2,2,CV_8UC3,Scalar(0,0,255));//CV_8UC3:8位的unsigned char,每個像素由3個元素組成三通道
cout<<”M=<<endl<<” “<<M<<endl<<endl;

2.C\C++中通過構造函數進行初始化

	int sz[3] = { 2,2,2 };Mat L(3, sz, CV_8UC3, Scalar::all(0));//創建超過2維的矩陣,指定維度,傳遞一個指向一個數組的指針,數組包含每個維度的尺寸

3.唯一存在的IplImage指針創建信息頭,轉換IplImage*->Mat

	//IplImage* img = cvLoadImage("1.jpg", 1);//Mat mtx(img); //報錯,"Mat沒有匹配IplImage*參數的構造函數"

4.利用Create()函數,此方法不能為矩陣設初值,只是在改變尺寸時重新為矩陣數據開辟內存

    M.create(4, 4, CV_8UC(2));cout << "M= " << endl << " " << M << endl << endl;

5.采用Matlab式的初始化方式

	Mat E = Mat::eye(4, 4, CV_64F);//單位矩陣cout << "E= " << endl << " " << E << endl << endl;Mat O = Mat::ones(2, 2, CV_32F);//全1矩陣cout << "O= " << endl << " " << O << endl << endl;Mat Z = Mat::zeros(3, 3, CV_8UC1);//全0矩陣cout << "Z= " << endl << " " << Z << endl << endl;

6.對小矩陣使用逗號分隔式初始化函數

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

7.為已存在的對象創建新信息頭

	Mat RowClone = C.row(1).clone();cout << "RowClone= " << endl << " " << RowClone << endl << endl;

4.1.5 OpenCV中格式化輸出方法

??r矩陣定義:通過randu()函數產生的隨機值來填充矩陣,需要給定一個上限和下限確保隨機值在期望的范圍內。

Mat r=Mat(10,3,CV_8UC3);
randu(r,Scalar::all(0),Scalar::all(255));
//1.OpenCV默認風格cout << "r (OpenCV默認風格)= " << r << ";" << endl << endl;
//2.Python風格cout << "r (Python風格)= " << format(r, Formatter::FMT_PYTHON) << ";" << endl << endl;
//3.逗號分隔風格cout << "r (逗號分隔風格)= " << format(r, Formatter::FMT_CSV) << ";" << endl << endl;
//4.Numpy風格cout << "r (Numpy風格)= " << format(r, Formatter::FMT_NUMPY) << ";" << endl << endl;
//5.C語言風格cout << "r (C語言風格)= " << format(r, Formatter::FMT_C) << ";" << endl << endl;

4.1.6 輸出其他常用數據結構

1.二維點

	Point2f p2f(6, 2);cout << "[二維點]p2f = " << p2f << ";\n" << endl;

2.三維點

	Point3f p3f(8, 2, 0);cout << "[二維點]p3f = " << p3f << ";\n" << endl;

3.基于Mat的std::vector

	vector<float>v;v.push_back(3);v.push_back(5);v.push_back(7);cout << "【基于Mat的vector】shortvec = " << Mat(v) << ";\n" << endl;

4.std::vector點,定義和輸出存放點的vector容器,以存放二維點Point2f為例

	vector<Point2f> points(20);for (size_t i = 0; i < points.size(); i++){points[i] = Point2f((float)(i * 5), (float)(i % 7));}cout << "[二維點向量]points = " << points << ";";

4.2 常用數據結構和函數

4.2.1 點的表示:Point類(OpenCV中Point_<int>、Point2i、Point等價,Point_<float>、Point2f等價)

	Point point;point.x = 10;point.y = 8;//Point point = Point(10, 8);

4.2.2 顏色的表示:Scalar類

??Scalar(a, b, c); 紅c,綠b,藍a

4.2.3 尺寸的表示:Size類(OpenCV中Size_、Size2i、Size等價)

	Size(5, 5);

4.2.4 矩形的表示:Rect類
(1)成員變量:x,y,width,height
(2)成員函數:Size(),area(),contains(Point),inside(Rect),tl()返回左上角點坐標,br()返回右下角點坐標
(3)求兩矩形交并集 Rect rect = rect1 & rect2; Rect rext = rext1 | rext2;
(4)矩形平移和縮放 Rect rextShift = rect + point; Rect rectScale = rect + size;

4.2.5 顏色空間轉換:cvtColor()函數
(1)函數原型:void cvtColor(InputArray src,OutputArray dst,int code,int dstCn=0)
(2)參數說明:輸入圖像,輸出圖像,顏色空間轉換標識符,目標圖像通道數
(3)示例: cvtColor(srcImage, dstImage, COLOR_GRAY2BGR);
????????
4.2.6 Core模塊中的常用函數
1.<math.h>中,計算向量角度fastAtan2、計算立方根cubeRoot、向上取整cvCeil、向下取整cvFloor、四舍五入cvRound、判斷自變量是否無窮大cvIsInf、判斷自變量是否不是一個數cvIsNaN
2.顯示文字相關:getTextSize、cvInitFont、putText
3.作圖相關:circle、clipLine、ellipse、ellipse2Poly、line、rectangle、polylines、LineIterator
4.填充相關:fillConvexPoly、fillPoly

4.3 基本圖形繪制

??涉及繪制函數:line:直線;ellipse:橢圓;rectangle:矩形;circle:圓形;fillPoly:填充的多邊形

#include<opencv2/opencv.hpp>
#include<opencv2/highgui.hpp>
#include<opencv2/imgproc/imgproc.hpp>
#define WINDOW_NAME1 "[繪制圖1]"
#define WINDOW_NAME2 "[繪制圖2]"
#define WINDOW_WIDTH 600      //定義窗口大小的宏
using namespace cv;
//4.3.1 DrawEllipse()函數
//自定義的繪制函數,實現繪制不同角度、相同尺寸的橢圓
void DrawEllipse(Mat img, double angle)
{int thickness = 2;//線寬int lineType = 8;//線形ellipse(img, Point(WINDOW_WIDTH / 2, WINDOW_WIDTH / 2), Size(WINDOW_WIDTH / 4, WINDOW_WIDTH / 16), angle, 0, 360, Scalar(255, 129, 0), thickness, lineType);
}//4.3.2 DrawFilledCircle()函數
//自定義的繪制函數,實現實心圓的繪制
void DrawFilledCircle(Mat img, Point center)
{int thickness = -1;int lineType = 8;circle(img, center, WINDOW_WIDTH / 32, Scalar(0, 0, 255), thickness, lineType);//圖像,圓心,半徑,顏色,線粗,線形
}
//4.3.3 DrawPolygon()函數
//自定義的繪制函數,實現凹多邊形的繪制
void DrawPolygon(Mat img)
{int lineType = 8;Point rookPoints[1][20];rookPoints[0][0] = Point(WINDOW_WIDTH / 4, 7 * WINDOW_WIDTH / 8);rookPoints[0][1] = Point(3 * WINDOW_WIDTH / 4, 7 * WINDOW_WIDTH / 8);rookPoints[0][2] = Point(3 * WINDOW_WIDTH / 4, 13 * WINDOW_WIDTH / 16);rookPoints[0][3] = Point(11 * WINDOW_WIDTH / 16, 13 * WINDOW_WIDTH / 16);rookPoints[0][4] = Point(19 * WINDOW_WIDTH / 32, 3 * WINDOW_WIDTH / 8);rookPoints[0][5] = Point(3 * WINDOW_WIDTH / 4, 3 * WINDOW_WIDTH / 8);rookPoints[0][6] = Point(3 * WINDOW_WIDTH / 4, WINDOW_WIDTH / 8);rookPoints[0][7] = Point(26 * WINDOW_WIDTH / 4, WINDOW_WIDTH / 8);rookPoints[0][8] = Point(26 * WINDOW_WIDTH / 4, WINDOW_WIDTH / 4);rookPoints[0][9] = Point(22 * WINDOW_WIDTH / 4, WINDOW_WIDTH / 4);rookPoints[0][10] = Point(22 * WINDOW_WIDTH / 4, WINDOW_WIDTH / 8);rookPoints[0][11] = Point(18 * WINDOW_WIDTH / 4, WINDOW_WIDTH / 8);rookPoints[0][12] = Point(18 * WINDOW_WIDTH / 4, WINDOW_WIDTH / 4);rookPoints[0][13] = Point(14 * WINDOW_WIDTH / 4, WINDOW_WIDTH / 4);rookPoints[0][14] = Point(14 * WINDOW_WIDTH / 4, WINDOW_WIDTH / 8);rookPoints[0][15] = Point(WINDOW_WIDTH / 4, WINDOW_WIDTH / 8);rookPoints[0][16] = Point(WINDOW_WIDTH / 4, 3 * WINDOW_WIDTH / 8);rookPoints[0][17] = Point(13 * WINDOW_WIDTH / 4, 3 * WINDOW_WIDTH / 8);rookPoints[0][18] = Point(5 * WINDOW_WIDTH / 4, 13 * WINDOW_WIDTH / 16);rookPoints[0][19] = Point(WINDOW_WIDTH / 4, 13 * WINDOW_WIDTH / 16);const Point* ppt[1] = { rookPoints[0] };//多邊形頂點集int npt[] = { 20 }; //多邊形頂點數目fillPoly(img, ppt, npt, 1, Scalar(255, 255, 255), lineType);//圖像,頂點集,頂點數目,要繪制的多邊形數量,顏色,線形
}
//4.3.4 DrawLine()函數
//自定義繪制函數,實現線的繪制
void DrawLine(Mat img, Point start, Point end)
{int thickness = 2;int lineType = 8;line(img, start, end, Scalar(0, 0, 0), thickness, lineType);
}
int main()
{//創建空白的Mat圖像Mat atomImage = Mat::zeros(WINDOW_WIDTH, WINDOW_WIDTH, CV_8UC3);Mat rookImage = Mat::zeros(WINDOW_WIDTH, WINDOW_WIDTH, CV_8UC3);//-------------------<1>繪制化學中的原子示例圖--------------------------//1.繪制橢圓DrawEllipse(atomImage, 90);DrawEllipse(atomImage, 0);DrawEllipse(atomImage, 45);DrawEllipse(atomImage, -45);//2.繪制圓心DrawFilledCircle(atomImage, Point(WINDOW_WIDTH / 2, WINDOW_WIDTH / 2));//-------------------------<2>繪制組合圖---------------------------//1.繪制橢圓DrawPolygon(rookImage);//2.繪制矩形rectangle(rookImage, Point(0, 7 * WINDOW_WIDTH / 8), Point(WINDOW_WIDTH, WINDOW_WIDTH), Scalar(0, 255, 255), -1, 8);//3.繪制一些線段DrawLine(rookImage, Point(0, 15 * WINDOW_WIDTH / 16), Point(WINDOW_WIDTH, 15 * WINDOW_WIDTH / 16));DrawLine(rookImage, Point(WINDOW_WIDTH/4, 7 * WINDOW_WIDTH / 8), Point(WINDOW_WIDTH/4, WINDOW_WIDTH));DrawLine(rookImage, Point(WINDOW_WIDTH / 2,7 * WINDOW_WIDTH/8), Point(WINDOW_WIDTH/2, WINDOW_WIDTH));DrawLine(rookImage, Point(3 * WINDOW_WIDTH/4, 7 * WINDOW_WIDTH / 8), Point(3 * WINDOW_WIDTH/4, WINDOW_WIDTH));//顯示繪制圖像imshow(WINDOW_NAME1, atomImage);cvMoveWindow(WINDOW_NAME1, 0, 200);imshow(WINDOW_NAME2, rookImage);cvMoveWindow(WINDOW_NAME2, WINDOW_WIDTH, 200);waitKey(0);return 0;
}

4.4 顏色空間拓展

??圖像彩色模型包括RGB模型、CMY模型、HSI模型、YIQ模型、YUV模型、YCbCr模型等

4.4.1 RGB彩色模型

??RGB彩色模型基于笛卡爾坐標系統,紅、綠、藍、青、深紅、黃、黑和白分別位于立方體各個頂點,灰度級沿黑和白兩點的連線分布。不同的顏色可以用從原點分布的向量來定義。歸一化彩色子空間立方體如圖所示:
????????????????

4.4.2 HSI彩色模型

??用色調、飽和度和強度描述彩色圖像。飽和度是純彩色被白光沖淡程度的度量,色調是用來描述純色的屬性,強度(灰度)是單色圖像的描述算子。該模型可從彩色信息中消除強度分量的影響,更符合人類的視覺特性,是一種理想的彩色圖像處理工具。

4.4.3 RGB與HSI彩色模型之間的轉換

(1)RGB轉換為HSI

??色調分量轉換公式:
??????????????????
??其中,
??????????????
??飽和度分量轉換公式:
??????????????????
??亮度分量轉換公式:
????????????????????

(2)HSI轉換為RGB

??RG區():若H在這個區域內,RGB分量公式為:
???????????????????
??GB區():若H在這個區域內,RGB分量公式為:
???????????????????
??BR區():若H在這個區域內,RGB分量公式為:
???????????????????

總結

以上是生活随笔為你收集整理的《OpenCV3编程入门》学习笔记4 OpenCV数据结构与基本绘图的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。