數字圖像處理其實就是處理二維矩陣資料。利用opencv來學習處理算法是一種比較好的方式。學習opencv,主要就是調用其中的圖像處理函數來實作各種操作。如果要得到想要的處理結果,還需要對圖像處理算法有一定的了解。同時,可能也有自己想寫一些算法的沖動,并急切的想驗證自己寫的算法是否能夠滿足處理的要求。可是,真正到自己動手寫的時候,總發現無從下手,比如,想得到圖像中的ROI區域(感興趣區域),想對圖像做加減運算算,将兩幅圖像連接配接成一幅圖像等等。如果要想随心所欲的按照自己的想法來操作一幅圖像,則需要對opencv的mat資料操作非常熟練,建議初學者将這些基本的操作背下來,然後你會發現,你再進行這樣的操作将是得心應手。
在opencv中對圖像資料進行操作,我們可以簡單的把mat資料看成一個二維數,裡面存儲的就是圖像的資料,是以,對mat數組的操作就是在操作二維圖像資料。下面我們來實作常見的Mat資料操作。
首先,在c++中建立一個空的控制台程式,然後,在屬性管理器中添加我們之前設定好的opencv4.0配置檔案,回到解決方案界面,選擇源檔案,右鍵添加新項目,然後得到一個空白的源檔案,如圖1和圖2所示。
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLicmbw5SN4AjZzEzMxkTNwIzNwQGN5UTM1EWZ4Q2NxQmZ2ATNj9CX0JXZ252bj91Ztl2Lc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
圖1添加配置好的opencv配置檔案
圖2 添加空白的源檔案
然後,就可以在這個空白的源檔案中寫代碼了。下面用具體的代碼來說明怎麼操作mat資料。下面的代碼都可以直接複制到自己的工程中直接運作如果涉及到要打開圖像檔案的,直接替換代碼中的檔案路徑為自己電腦中的圖像路徑就可以了。
int main(int argc, char** argv){//構造3X3的Mat矩陣// CV_8UC1和CV_8UC3是資料類型和通道,指8位無符号單通道和3資料,通道資料Mat a(Size(3,3),CV_8UC1);Mat b = Mat(Size(3,3),CV_8UC3);cout<
opencv 把3通道圖像轉成單通道_數字圖像處理之opencv中Mat資料操作
圖3 輸出構造的mat資料
圖3是上面代碼輸出的結果,a是單通道,b是三通道,是以b是3行9列。裡面的具體的值是opencv随機自動給的,因為我們還沒有對mat指派,這個不用管。再來看幾個操作,
Mat mz = Mat::zeros(Size(5,5),CV_8UC1);//構造5X5的全是0的mat資料
Mat mo = Mat::ones(Size(5,5),CV_8UC1);// 構造5X5的全是1的mat資料
Mat me = Mat::eye(Size(5,5),CV_8UC1); 構造5X5的機關矩陣的mat資料
上面的代碼可以直接在上面的main函數裡面接着往下寫。圖4是輸出結果
opencv 把3通道圖像轉成單通道_數字圖像處理之opencv中Mat資料操作
圖4 上面三行代碼的輸出結果
接着往下寫。
下面我們重新寫一個main函數,不自己構造mat資料,直接從圖像中得到。然後對圖像資料的mat進行操作
opencv 把3通道圖像轉成單通道_數字圖像處理之opencv中Mat資料操作
圖5 輸出結果顯示
上面包括了mat資料的主要操作指令,如果能夠把這些指令記住了,要對圖像做一般的操作基本上沒有什麼問題了。
此外,如果要通路圖像中的每一個像素值,可以采用下面指針的方式,速度是最快的。下面的代碼隻是示範了怎麼使用指針通路像素,沒有什麼特别的目的。
Mat dyImg = Mat(src1.rows, src1.cols,0);
for(int i=0;i
{
uchar* srcdata = src1.ptr(i);
uchar* dydata = dyImg.ptr(i);
for(int j=0;j< src1.cols;j++)
{
double tempValue = double(srcdata [j]) + 20.0;
if(tempValue < 0)
dydata[j] = 0;
else if(tempValue > 255)
dydata[j] = 255;
else
dydata[j] = tempValue;
}
}
namedWindow("dyImg ",0);
imshow("dyImg ", dyImg);