Opencv學習(一)之Mat類
阿新 • • 發佈:2019-02-02
作為初學者,我對於Opencv的學習總是比較迷茫,還好可以借鑑別人的部落格。
Mat類的內容比較多,這次我也只是對它有個基礎、淺層的認識,在以後的學習和應用中我會根據需要和例項再不斷補充學習。
一 背景
在Opencv1.X時代,資料型別為 IpIImage;
在Opencv2.X時代,資料型別為Mat.現在Mat更為常見。
二 用途
Mat類最重要的用途是作為儲存影象的資料結構。至於Mat類如何儲存影象(灰度圖/彩色圖),我參考的是別人的一篇部落格。
http://lib.csdn.net/article/opencv/42000
暫且知道Mat由矩陣頭(包含矩陣的大小、儲存方法等)和一個指向矩陣的指標構成。
三 Mat如何讀取影象的內容
在此主要介紹兩種方法(借鑑別人的部落格寫了個例程供自己學習)
方法一:at操作(操作物件:灰度影象)
#include <opencv2/opencv.hpp> #include <iostream> using namespace std; using namespace cv; int main() { Mat image = imread("D:\\Tencent\\test.jpg"); //存放自己影象的路徑 //namedWindow("Show");//在這裡加不加這條語句,效果一樣 imshow("Show", image); waitKey(0); resize(image, image, Size(375, 500));//resize為500*375的影象 cvtColor(image, image, CV_RGB2GRAY);//轉為灰度圖 imshow("image_ori", image); waitKey(0); for (int i = 0; i < image.rows; i++) { for (int j = 0; j < image.cols; j++) { image.at<uchar>(i, j) = i + j; } } imshow("image_res",image); waitKey(0); return 0; }
以上是對於灰度影象的處理,對於彩色影象的處理只需要把at<型別>中的型別改為Vec3b即可
例程如下:
#include <opencv2/opencv.hpp> #include <iostream> using namespace std; using namespace cv; int main() { Mat image = imread("D:\\Tencent\\test.jpg"); //存放自己影象的路徑 /*namedWindow("Show");*/ imshow("Show", image); resize(image, image, Size(375, 500));//resize為500*375的影象 //cvtColor(image, image, CV_RGB2GRAY);//轉為灰度圖 //imshow("image_ori", image); for (int i = 0; i < image.rows; i++) { for (int j = 0; j < image.cols; j++) { /*image.at<uchar>(i, j) = i + j;*/ //iamge.at<Vec3b>(i, j)[0] = 255;//對於藍色通道進行操作 image.at<Vec3b>(i, j)[1] = 255;//對於綠色通道進行操作 //img.at<Vec3b>(i, j)[2] = 255;//對於紅色通道進行操作 } } imshow("image_res",image); waitKey(0); return 0; }
方法二:採用指標對影象進行訪問
以下給出對彩色影象操作的例程
#include <opencv2\highgui\highgui.hpp>
#include <opencv2\imgproc\imgproc.hpp>
#include <opencv2\core\core.hpp>
#include <iostream>
using namespace cv;
using namespace std;
int main()
{
Mat img = imread("D:\\Tencent\\test.jpg");
int rows = img.rows;//矩陣行
int cols = img.cols * img.channels();//彩色影象的列
if (img.isContinuous())//判斷是否在記憶體中連續
{
cols = cols * rows;
rows = 1;//如果連續,則為一行
}
imshow("ori", img);
for (int i = 0; i<rows; i++)//控制行
{
//調取儲存影象記憶體的第i行的指標
uchar *pointer = img.ptr<uchar>(i);
for (int j = 0; j<cols; j += 3)
{
//pointer[j] = 255;//對藍色通道進行操作
//pointer[j+1] = 255;//對綠色通道進行操作
pointer[j + 2] = 255;//對紅色通道進行操作
}
}
imshow("result", img);
waitKey();
return 0;
}
四 Mat類中常用的變數引數(Mat的宣告在core.hpp中)
Mat類中有很多的變數引數,先熟悉以下幾個:
- size(cols,rows) cols-列數,rows-行數
- CV_8UC3 其中8U表示8位無符號整數,C後為通道數
- Mat M1(3,2,cv_8uc3,scalar(0,0,225)); 定義Mat類的M為一個3行,2列,每列由3個元素(0,0,225)構成的 矩陣,其中的scalar()完成對每個元素的賦值。
- Mat M2(size(3,2),cv_8uc3,scalar(1,2,3));
- Mat M3(M2);
- step1(i)表示的是Mat中的每一維的通道數
- step[i]表示Mat中的每一維的大小(以位元組為單位)
- size[i]表示Mat中元素的個數
- elemSize()表示每個元素的大小(以位元組為單位)
通過例項理解上面定義物件的含義
#include <opencv2\highgui\highgui.hpp>
#include <opencv2\imgproc\imgproc.hpp>
#include <opencv2\core\core.hpp>
#include <iostream>
#include <time.h>
using namespace cv;
using namespace std;
int main()
{
Mat img = imread("D:\\Tencent\\test.jpg");
cout << "img.rows: " << img.rows <<endl<< " img.cols: " << img.cols <<endl<< " img.channels(): " << img.channels() << endl;
cout << "**********************" << endl;
cout << "img.step1(0): " << img.step1(0) << endl;
cout << "img.step1(1): " << img.step1(1) << endl;
cout << "img.step[0]: " << img.step[0] << endl;
cout << "img.step[1]: " << img.step[1] << endl;
cout << "img.size[0]: " << img.size[0] << endl;
cout << "img.size[1]: " << img.size[1] << endl;
cout << "img.elemSize(): " << img.elemSize() << endl;
cout << "img.elemSize1(): " << img.elemSize1() << endl;
uchar response;
cin >> response;
return 0;
}
由於剛學者用部落格,只會載入圖片,還不知道咋載入執行視窗,所以目前所有的例項都沒有上傳執行結果,但親測無誤。部落格是一個很好的平臺,寫部落格對自己的知識是一種歸練,對別人也是一種幫助,我會緊跟大神步伐不斷完善的。