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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 人工智能 > 循环神经网络 >内容正文

循环神经网络

创建mat二值图 matlab,OpenCV学习之路(二)——Mat对象

發布時間:2025/4/5 循环神经网络 42 豆豆
生活随笔 收集整理的這篇文章主要介紹了 创建mat二值图 matlab,OpenCV学习之路(二)——Mat对象 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

早期的 OpenCV 中,使用 IplImage 和 CvMat 數據結構來表示圖像。IplImage和 CvMat 都是 C 語言的結構。使用這兩個結構的問題是內存需要手動管理,開發者必須清楚的知道何時需要申請內存,何時需要釋放內存。這個開發者帶來了一定的負擔,開發者應該將更多精力用于算法設計,因此在新版本的 OpenCV 中引入了 Mat 類。

新加入的 Mat 類能夠自動管理內存。使用 Mat 類,你不再需要花費大量精力在內存管理上。而且你的代碼會變得很簡潔,代碼行數會變少。但 C++接口唯一的不足是當前一些嵌入式開發系統可能只支持 C 語言,如果你的開發平臺支持C++,完全沒有必要再用 IplImage 和 CvMat。在新版本的 OpenCV 中,開發者依然可以使用 IplImage 和 CvMat,但是一些新增加的函數只 供了 Mat 接口。

Mat 類的定義如下所示,關鍵的屬性如下方代碼所示:

class CV_EXPORTS Mat

{

public:

//一系列函數

...

/* flag 參數中包含許多關于矩陣的信息,如:

-Mat 的標識

-數據是否連續

-深度

-通道數目

*/

int flags;

//矩陣的維數,取值應該大于或等于 2

int dims;

//矩陣的行數和列數,如果矩陣超過 2 維,這兩個變量的值都為-1

int rows, cols;

//指向數據的指針

uchar* data;

//指向引用計數的指針

//如果數據是由用戶分配的,則為 NULL

int* refcount;

//其他成員變量和成員函數

...

};

Mat屬性的理解

data:uchar類型的指針,指向Mat數據矩陣的首地址。可以理解為標示一個房屋的門牌號;

dims:Mat矩陣的維度,若Mat是一個二維矩陣,則dims=2,三維則dims=3,大多數情況下處理的都是二維矩陣,是一個平面上的矩陣;

rows:Mat矩陣的行數。可理解為房屋內房間行數;

cols:Mat矩陣的列數。可理解為房屋內房間列數;

size():首先size是一個結構體,定義了Mat矩陣內數據的分布形式,數值上有關系式:

image.size().width==image.cols;

image.size().height==image.rows;

可以理解為房屋內房間的整體布局,這其中包括了房間分別在行列上分布的數量信息;

channels():Mat矩陣元素擁有的通道數。例如常見的RGB彩色圖像,channels==3;而灰度圖像只有一個灰度分量信息,channels==1。可以理解為每個房間內放有多少床位,3通道的放了3張床,單通道的放了1張床;

depth:用來度量每一個像素中每一個通道的精度,但它本身與圖像的通道數無關!depth數值越大,精度越高。在Opencv中,Mat.depth()得到的是一個0~6的數字,分別代表不同的位數,對應關系如下:

enum{CV_8U=0, CV_8S=1, CV_16U=2, CV_16S=3, CV_32S=4, CV_32F=5, CV_64F=6}

可見 0和1都代表8位,2和3都代表16位,4和5代表32位,6代表64位;其中U是unsigned的意思,S表示signed,也就是有符號和無符號數。可以理解為房間內每張床可以睡多少人,這個跟房間內有多少床并無關系;

elemSize:elem是element(元素)的縮寫,表示矩陣中每一個元素的數據大小,如果Mat中的數據類型是CV_8UC1,那么elemSize==1;如果是CV_8UC3或CV_8SC3,那么elemSize==3;如果是CV_16UC3或者CV_16SC3,那么elemSize==6;即elemSize是以8位(一個字節)為一個單位,乘以通道數和8位的整數倍;可以理解為整個房間可以睡多少人,這個時候就得累計上房間內所有床位數(通道)和每張床的容納量了;

elemSize1:elemSize加上一個“1”構成了elemSize1這個屬性,1可以認為是元素內1個通道的意思,這樣從命名上拆分后就很容易解釋這個屬性了:表示Mat矩陣中每一個元素單個通道的數據大小,以字節為一個單位,所以有:

eleSize1==elemSize/channels;

step:可以理解為Mat矩陣中每一行的“步長”,以字節為基本單位,每一行中所有元素的字節總量,是累計了一行中所有元素、所有通道、所有通道的elemSize1之后的值;

step1():以字節為基本單位,Mat矩陣中每一個像素的大小,累計了所有通道的elemSize1之后的值,所以有:

step1==step/elemSize1;

M.step[m-1] 總是等于 elemSize;M.step1(m-1)總是等于 channels。

補充:

step1(i):每一維元素的通道數

step[i]:每一維元素的大小,單位字節

size[i]:每一維元素的個數

elemSize():每個元素大小,單位字節

elemSize1():每個通道大小,單位字節

每一維的元素表示什么意思呢?

這里我們以空間幾何的角度來解釋,能夠更加容易理解一點。

三維矩陣,一共有三維,我們分別類比為

面:每個二維矩陣,表示第1維的元素

線:矩陣的每一行,表示第2維的元素

點:矩陣中每行的每個元素,表示第3維的元素

那么這樣子就可以解釋清楚每一維元素的含義了。

以step[i]為例

step[0]:面的大小,第1維的元素的大小,也就是二維矩陣的大小,一個二維矩陣有8行,所以

step[0] = step[1] * 8 = 480

step[1]:線的大小,第2維的元素的大小,也就是二維矩陣每一行的大小,由于每個元素大小為6,每行有10個元素,所以

step[1] = 10 * 6 = 60

step[2]:點的大小,第3維的元素的大小,這里矩陣的每個元素類型為CV_16UC3,所以

step[2] = 2 * 3 = 6

這里注意:

1.step的大小是字節

2.注意下標與維數的對應關系:下標2對應點,1對應線,0對應面

3.矩陣有幾維,step[]數組就有幾個元素,如3維,則有3個元素,step[0],step[1],step[2].分別對應面,線,點

只要記住,最后一個總是表示點,然后依次向前為線,面...

4.第2,3 點 ,對于size和step1()也一樣。

step1(i)和size[]與step[i]原理相同。

Mat對象構造函數與常用方法

常用的構造函數有:

Mat::Mat()

無參數構造方法;

Mat::Mat(int rows, int cols, int type)

創建行數為 rows,列數為 col,類型為 type 的圖像;

Mat::Mat(Size size, int type)

創建大小為 size,類型為 type 的圖像;

Mat::Mat(int rows, int cols, int type, const Scalar& s)

創建行數為 rows,列數為 col,類型為 type 的圖像,并將所有元素初始化為值 s;

Mat::Mat(Size size, int type, const Scalar& s)

創建大小為 size,類型為 type 的圖像,并將所有元素初始化為值 s;

Mat::Mat(const Mat& m)

將 m 賦值給新創建的對象,此處不會對圖像數據進行復制,m 和新對象共用圖像數據;

Mat::Mat(int rows, int cols, int type, void* data, size_t step=AUTO_STEP)

創建行數為 rows,列數為 col,類型為 type 的圖像,此構造函數不創建圖像數據所需內存,而是直接使用 data 所指內存,圖像的行步長由 step指定。

Mat::Mat(Size size, int type, void* data, size_t step=AUTO_STEP)

創建大小為 size,類型為 type 的圖像,此構造函數不創建圖像數據所需內存,而是直接使用 data 所指內存,圖像的行步長由 step 指定。

Mat::Mat(const Mat& m, const Range& rowRange, const Range& colRange)

創建的新圖像為 m 的一部分,具體的范圍由 rowRange 和 colRange 指定,此構造函數也不進行圖像數據的復制操作,新圖像與 m 共用圖像數據;

Mat::Mat(const Mat& m, const Rect& roi)

創建的新圖像為 m 的一部分,具體的范圍 roi 指定,此構造函數也不進行圖像數據的復制操作,新圖像與 m 共用圖像數據。

這些構造函數中,很多都涉及到類型 type。type 可以是 CV_8UC1,CV_16SC1,...,CV_64FC4 等。里面的 8U 表示 8 位無符號整數,16S 表示 16 位有符號整數,64F表示 64 位浮點數(即 double 類型);C 后面的數表示通道數,例如 C1 表示一個通道的圖像,C4 表示 4 個通道的圖像,以此類推。

如果你需要更多的通道數,需要用宏 CV_8UC(n),例如:

Mat M(3,2, CV_8UC(5));//創建行數為3,列數為2,通道數為5的圖像

有些 type 參數如 CV_32F未注明通道數目,這種情況下它表示單通道。

常用方法

void copyTo(); //拷貝

Mat clone(); //拷貝

int channels(); //通道,矩陣中的每一個矩陣元素擁有的值的個數

int depth(); //深度,即每一個像素的位數(bits)

bool empty() const; //判斷是否為空

uchar* ptr(int i0=0); //指針取第0行數據

void convertTo(oclMat& m, int rtype, double alpha=1, double beta=0);

//m:轉為目標數據類型的矩陣;

//rtype: 指定目標數據類型,或者是depth(通道數),如果rtype:是負值,那么目標矩陣的數據類型和源矩形的數據類型是一致的;

//alpha:基于尺度的變化值;

//beta:在尺度上的加和;

Mat類的內存管理

Mat 是一個類,由兩個數據部分組成:矩陣頭(包含矩陣尺寸,存儲方法,存儲地址等信息)和一個指向存儲所有像素值的矩陣的指針。矩陣頭的尺寸是常數值,但矩陣本身的尺寸會依圖像的不同而不同,通常比矩陣頭的尺寸大數個數量級。復制矩陣數據往往花費較多時間,因此除非有必要,不要復制大的矩陣。

為了解決矩陣數據的傳遞,OpenCV 使用了引用計數機制。其思路是讓每個Mat 對象有自己的矩陣頭信息,但多個 Mat 對象可以共享同一個矩陣數據。讓矩陣指針指向同一地址而實現這一目的。很多函數以及很多操作(如函數參數傳值)只復制矩陣頭信息,而不復制矩陣數據。

如果 Mat 類自己申請數據空間,那么該類會多申請 4 個字節,多出的 4 個字節存儲數據被引用的次數。引用次數存儲于數據空間的后面,refcount 指向這個位置,如圖所示。當計數等于 0 時,則釋放該空間。

Mat類.jpeg

關于多個矩陣對象共享同一矩陣數據,我們可以看這個例子:

Mat A(100,100, CV_8UC1);

Mat B = A;

Mat C = A(Rect(50,50,30,30));

上面代碼中有三個Mat對象,分別是A,B和C。這三者共有同一矩陣數據,其示意圖如圖:

三個矩陣頭共用共用同一矩陣數據.jpeg

部分復制:一般情況下只會復制Mat對象的頭和指針部分,不會復制數據部分。如:

Mat A = imread(filePath);

Mat B = A;

完全復制:如果想把Mat對象的頭部和數據部分一起復制,如下:

Mat F = A.clone();

Mat G;

A.copyTo(G);

四個要點:

輸出圖像的內存是自動分配的

使用OpenCV的C++接口,不需要考慮內存分配的問題

賦值操作和拷貝構造函數只會復制頭部分

使用clone()與copyTo()兩個函數實現數據完全復制

create()函數創建對象

除了在構造函數中可以創建圖像,也可以使用 Mat 類的 create()函數創建圖像。如果 create()函數指定的參數與圖像之前的參數相同,則不進行實質的內存申請操作;如果參數不同,則減少原始數據內存的索引,并重新申請內存。使用方法如下面例程所示:

Mat M(2,2, CV_8UC3);//構造函數創建圖像

M.create(3,2, CV_8UC2);//釋放內存重新創建圖像

需要注意的時,使用 create()函數無法設置圖像像素的初始值。

Matlab 風格的創建對象方法

OpenCV 2 中 供了 Matlab 風格的函數,如 zeros(),ones()和 eyes()。這種方法使得代碼非常簡潔,使用起來也非常方便。使用這些函數需要指定圖像的大小和類型,使用方法如下:

Mat Z = Mat::zeros(3, 3, CV_8UC1);

cout << "Z = " << endl << " " << Z << endl;

Mat O = Mat::ones(3, 3, CV_32F);

cout << "O = " << endl << " " << O << endl;

Mat E = Mat::eye(3, 3, CV_64F);

cout << "E = " << endl << " " << E << endl;

show.jpeg

Mat 與 IplImage 和 CvMat 的轉換

1.Mat 轉為 IplImage 和 CvMat 格式

假如你有一個以前寫的函數,函數的定義為:

void mycvOldFunc(IplImage * p, ...);

函數的參數需要 IplImage 類型的指針。Mat 轉為 IplImage,可以用簡單的等號賦值操作來進行類型轉換,這樣實現:

Mat img(Size(320, 240), CV_8UC3);

...

IplImage iplimg = img; //轉為IplImage結構

mycvOldFunc( & iplimg, ...);//對 iplimg 取地址

如果要轉為 CvMat 類型,操作類似:

CvMat cvimg = img; //轉為CvMat結構

需要特別注意的是,類型轉換后,IplImage 和 CvMat 與 Mat 共用同一矩陣數據,而 IplImage 和 CvMat 沒有引用計數功能,如果上例中的 img 中數據被釋放,iplimg 和 cvimg 也就失去了數據。因此要牢記不可將 Mat 對象 前釋放。

2.IplImage 和 CvMat 格式轉為 Mat

Mat 類有兩個構造函數,可以實現 IplImage 和 CvMat 到 Mat 的轉換。這兩個函數都有一個參數 copyData。如果 copyData 的值是 false,那么 Mat 將與 IplImage或 CvMat 共用同一矩陣數據;如果值是 true,Mat 會新申請內存,然后將 IplImage或 CvMat 的數據復制到 Mat 的數據區。

如果共用數據,Mat 也將不會使用引用計數來管理內存,需要開發者自己來管理。

Mat::Mat(const CvMat* m, bool copyData=false)

Mat::Mat(const IplImage* img, bool copyData=false)

例子代碼如下:

IplImage * iplimg = cvLoadImage("lena.jpg");

Mat im(iplimg, true);

總結

以上是生活随笔為你收集整理的创建mat二值图 matlab,OpenCV学习之路(二)——Mat对象的全部內容,希望文章能夠幫你解決所遇到的問題。

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

主站蜘蛛池模板: 中文字幕人妻色偷偷久久 | 成人av网站在线 | www.久久艹| 香蕉网在线播放 | 精品视频在线看 | 日本人做受免费视频 | 黄金网站在线观看 | 91麻豆国产在线 | 双性皇帝高h喷汁呻吟 | 国产精品成人国产乱一区 | 成人免费在线 | 91精品国产色综合久久不卡粉嫩 | 欧美成人怡红院 | 在办公室被c到呻吟的动态图 | 你懂的在线网站 | 未满十八岁禁止进入 | 日本在线激情 | 又紧又大又爽精品一区二区 | 国产精品久久久久久白浆 | 国产精品三级久久久久久电影 | 中文字幕网站在线观看 | 久久瑟瑟 | 亚洲国产天堂av | 特黄做受又粗又大又硬老头 | 精品成人一区二区 | 日本免费一区二区视频 | 一本一道人人妻人人妻αv 九一在线视频 | 91香蕉国产在线观看 | 成熟人妻av无码专区 | 日本www高清| 天堂资源 | va在线视频 | 中文久久字幕 | 69超碰| 无码一区二区精品 | 欧美性猛交xxx乱大交3蜜桃 | 久久久久久久久久久久久女过产乱 | 日本成人午夜视频 | 亚洲AV永久无码国产精品国产 | 天堂а√在线中文在线 | 99自拍视频在线观看 | 亚洲毛片a | 欧美伦理影院 | 欧美精选一区二区 | 午夜精品久久久久久久久 | 成人a区| 在线观看免费观看在线 | 色网站在线观看 | 超碰激情 | 成年人免费大片 | 竹菊影视一区二区三区 | 姐姐你真棒插曲快来救救我电影 | 中文理论片 | 我的丝袜美腿尤物麻麻 | 欧美三级理论片 | 老司机午夜精品视频 | 久久久精品一区二区三区 | 国产学生美女无遮拦高潮视频 | 国产精品无码在线 | 久久久亚洲一区二区三区 | jizzjizz8| 动漫一区二区三区 | 97福利| 精品熟女一区二区三区 | 色一涩| 天天5g天天爽免费观看 | 小泽玛利亚一区二区三区在线观看 | 午夜影院网站 | 免费污片网站 | 日韩av一卡二卡 | 日本亚洲黄色 | 欧美另类videosbestsex日本 | 日韩中文字幕网址 | 日韩中文字幕 | 国产第一页屁屁影院 | 日本视频黄 | 上原亚衣av一区二区三区 | www.国产高清 | 欧美熟妇乱码在线一区 | 小视频成人 | 最新国产网站 | 在线欧美日韩国产 | 国产精品系列在线播放 | 色呦呦在线播放 | avtt在线播放 | 亚洲自拍中文字幕 | 在线观看aa | 一区精品二区国产 | 一区二区国产电影 | 欧美三级欧美一级 | 香蕉视频免费网站 | 另类专区欧美 | 成人在线视频一区二区三区 | 狠狠干夜夜骑 | 影音先锋中文字幕一区二区 | 亚洲最大中文字幕 | 欧美在线一区二区三区 | 91精品国产自产精品男人的天堂 | 宿舍女女闺蜜调教羞辱 |