教面試官ReentrantLock源碼
850
2025-03-31
2.5 理解Mat類
參考上一章對計算機視覺中圖像的描述,任何一個圖像實際上都是一個給定寬度、長度、顏色通道數(shù)量和深度的矩陣。基于此描述,我們可以說OpenCV Mat類能用來處理圖像數(shù)據(jù),而且它支持圖像所需的所有屬性,比如寬度和高度。事實上,Mat類是一個n維數(shù)組,用來存儲任意給定數(shù)據(jù)類型的單通道或多通道數(shù)據(jù),并且它包含了大量成員和方法,以多種方式創(chuàng)建、修改或操作這些數(shù)據(jù)。
本節(jié)我們將通過實際范例和代碼示例來學(xué)習(xí)Mat類中一些最重要的成員和方法。
OpenCV C++ Mat類在Python版本中的等價類并不是原生的OpenCV類,而是被表示為 numpy.ndarray的數(shù)據(jù)類型。NumPy是一個Python庫,包括了大量數(shù)值算法和數(shù)學(xué)運算方法,并且支持大型的多維數(shù)組和矩陣。在Python版本中使用numpy.ndarray數(shù)據(jù)類型的原因,是它提供了C++版本OpenCV Mat類所需成員和方法的最佳替代品(如果不完全相同的話)。完整的numpy.ndarray所支持的成員和方法列表請參考NumPy說明文檔。
2.5.1 創(chuàng)建一個Mat對象
基于不同的初始化要求,Mat類包含大約20種不同的構(gòu)造函數(shù)來創(chuàng)建類實例。讓我們通過示例來看看最常用的構(gòu)造函數(shù)。
創(chuàng)建一個Mat對象(或者類的實例),寬度1920,高度1080,包含32位浮點數(shù)表示的3個顏色通道,如下所示:
注意,Mat構(gòu)造函數(shù)中的type參數(shù)可被看成一種特殊類型的參數(shù),也就是一個包含深度、數(shù)據(jù)類型和顏色通道數(shù)的常量。格式如下:
你可以用以下構(gòu)造函數(shù)來創(chuàng)建一個寬度為W、高度為H的8位無符號3通道RGB圖像,然后用R、G和B的顏色值初始化所有元素:
注意,OpenCV中顏色的默認存儲順序是BGR(而不是RGB),這意味著B和R交換了位置。如果我們的目標是在程序運行時的某個時間點顯示處理過的圖像,這一點尤其重要。
因此,前面的代碼中正確的scalar初始化方法應(yīng)該如下:
如果我們需要創(chuàng)建一個高維Mat對象,可以按如下方法。注意,在下面的例子中一個7維的Mat對象被創(chuàng)建。sizes數(shù)組提供了每一維的大小,高維Mat中的每一個元素被稱為hdm,它包含32位浮點數(shù)的雙通道:
用C++向量也可以實現(xiàn)相同的功能,方法如下:
類似地,我們可以使用另外的Scalar參數(shù)來初始化Mat對象中所有的數(shù)值。注意,Scalar中的數(shù)值個數(shù)必須與通道數(shù)一致。例如,初始化上述的7維Mat對象中的所有元素,我們需要用到下面的構(gòu)造函數(shù):
Mat類允許我們使用已經(jīng)存在的圖像數(shù)據(jù)進行初始化。使用這個構(gòu)造函數(shù),你可以使Mat類中的data指針所指向的數(shù)據(jù)相同。注意,這個構(gòu)造函數(shù)并不是創(chuàng)建了一個初始化數(shù)據(jù)的完整拷貝,而是使創(chuàng)建的Mat對象的指針指向了它的地址。這就能非常高效地初始化和構(gòu)造Mat類,但是有一個特別明顯的缺點是在不再需要該類時要注意內(nèi)存清理,所以在使用這個構(gòu)造函數(shù)時要格外小心:
注意,與前面的構(gòu)造函數(shù)及其初始化不同,這里的data類型不是Scalar,而是指向一塊內(nèi)存的指針,所指向的內(nèi)存含有一個1920×1080像素的三通道圖像數(shù)據(jù)。這種用指針指向內(nèi)存空間的初始化Mat對象方法同樣適用于高維的Mat類。
最后一種構(gòu)造函數(shù)類型,同時也是Mat類中最重要的構(gòu)造函數(shù)之一,被稱為感興趣區(qū)域(Region Of Interest,ROI)構(gòu)造函數(shù)。此構(gòu)造函數(shù)用另一個Mat對象中的一個區(qū)域來初始化Mat對象。讓我們用一個例子來說明。假設(shè)你有一個圖像,你想對圖像中的特定區(qū)域,或者說ROI,進行修改。你可以使用下面的構(gòu)造函數(shù)來創(chuàng)建一個可訪問ROI的Mat類,而且對該區(qū)域的任何更改都會影響到原始圖像的相同區(qū)域。我們用下面的代碼來實現(xiàn):
當(dāng)image(它本身是Mat對象)包含下面左邊的圖片時,如果用上面的構(gòu)造函數(shù),那么roi將能訪問圖像中框出的區(qū)域,并包含顯示在右邊的圖像:
Rect類在OpenCV中用來表示一個給定了左上角點以及寬度和高度的矩形,例如,在上面的例子中Rect類的左上角點的位置為240和140,寬度為300,高度為300,如下所示:
如前所述,對ROI的任何改動都會造成原始圖像的更改。例如,我們可以將以下圖像處理算法應(yīng)用到roi(現(xiàn)在先不深究該算法,我們將會在后續(xù)章節(jié)中學(xué)習(xí)它,只需關(guān)注ROI的概念):
如果我們嘗試顯示這個圖像,結(jié)果應(yīng)該接近下圖。注意在此圖中,上面圖像中標注的區(qū)域被改變了(膨脹了),盡管我們改變的只是roi,而不是原圖本身:
類似于在一個圖像的矩形區(qū)域使用Rect類來構(gòu)造一個ROI Mat類對象一樣,你同樣也可以在原始的Mat對象中創(chuàng)建一個對應(yīng)一個行和列區(qū)間的ROI。例如,上述例子的相同區(qū)域也可以被以下的構(gòu)造函數(shù)訪問:
Range類在OpenCV中用來表示start和end的區(qū)間。根據(jù)start和end的數(shù)值,可以檢查Range類是否為空。在上面的構(gòu)造函數(shù)中,第一個Range類表示原始圖像的從140行到440行的區(qū)間。第二個Range表示原始圖像的從240列到540列的區(qū)間。兩個區(qū)間所重疊的區(qū)域就是上面的ROI。
機器視覺 OpenCV
版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實的內(nèi)容,請聯(lián)系我們jiasou666@gmail.com 處理,核實后本網(wǎng)站將在24小時內(nèi)刪除侵權(quán)內(nèi)容。
版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實的內(nèi)容,請聯(lián)系我們jiasou666@gmail.com 處理,核實后本網(wǎng)站將在24小時內(nèi)刪除侵權(quán)內(nèi)容。