CV::Mat
Mat類(lèi)?(Matrix的縮寫(xiě)) 是OpenCV用于處理圖像而引入的一個(gè)封裝類(lèi),其功能十分強(qiáng)大,rows和cols參數(shù)代表圖像的2維矩陣的行數(shù) 列數(shù)
初始化方法
openCV 提供了很多初始化方法
在iOS 中通過(guò) UIImage 初始化
?? UIImage*inputImage = [UIImage imageNamed:@"XXX"];
? ? Mat imageSrc;
? ? UIImageToMat(inputImage, imageSrc);
/*
Mat(int _rows, int _cols, int _type, const cv::Scalar &_s)
第一個(gè)參數(shù) 列
第二個(gè)參數(shù) 行
第二個(gè)參數(shù) 圖片類(lèi)型
第四個(gè)參數(shù) 顏色
?*/
Mat imagesrc(100,100,CV_8UC3,Scalar(r,g,b));
圖片的復(fù)制
圖片的復(fù)制可以通過(guò)兩個(gè)函數(shù)來(lái)完成 分別是 ?clone() ? copyTo ?
clone是完全深考貝,即重新開(kāi)辟內(nèi)存
copyTo 也是深拷貝,但是否申請(qǐng)新的內(nèi)存空間贮尖,取決于dst矩陣頭中的大小信息是否與src一至炕倘,若一致則只深拷貝并不申請(qǐng)新的空間,否則先申請(qǐng)空間后再進(jìn)行拷貝
圖片的轉(zhuǎn)換
目前 openCV 主要只支持處理單通道和3通道的圖像套腹,并且此時(shí)要求其深度為8bit和16bit無(wú)符號(hào)(即CV_16U),所以其他一些數(shù)據(jù)類(lèi)型是不支持的,比如說(shuō)float型等加派。 如果Mat類(lèi)型數(shù)據(jù)的深度和通道數(shù)不滿足上面的要求則需要使用convertTo()函數(shù)和cvtColor()函數(shù)來(lái)進(jìn)行轉(zhuǎn)換卓舵。?
convertTo()函數(shù)負(fù)責(zé)轉(zhuǎn)換數(shù)據(jù)類(lèi)型不同的Mat南用,即可以將類(lèi)似float型的Mat轉(zhuǎn)換到imwrite()函數(shù)能夠接受的類(lèi)型。?
而cvtColor()函數(shù)是負(fù)責(zé)轉(zhuǎn)換不同通道的Mat
注意: ?有很多時(shí)候發(fā)現(xiàn)引進(jìn)來(lái)的圖片處理了,無(wú)效果,其實(shí)就是因?yàn)?openCV 主要只支持處理單通道和3通道的圖像,我們常引用的是ARGB類(lèi)型的圖片 一定要轉(zhuǎn)成RGB 3通道才能處理
示例
?UIImage *inputImage = [UIImage imageNamed:@"XXX"]; ? ?
//轉(zhuǎn)換成 Mat ? ?
Mat ? imageSrc; ? ?
UIImageToMat(inputImage, imageSrc); ?? ? ? ?
// convertTo 轉(zhuǎn)換成 3通道 ? ?
Mat ? imageSrc_dst1; ? ?
imageSrc.convertTo(imageSrc_dst1, CV_8UC3); ?? ? ? ?
//cvtColor 轉(zhuǎn)換 ? ? ?
Mat imageSrc_dst2; ? ?
cvtColor(imageSrc, imageSrc_dst2, CV_RGB2BGR,3); ?? ?
Mat::at
??cv::Mat的成員函數(shù):?.at(int y掏湾, int x)可以用來(lái)存取圖像中對(duì)應(yīng)坐標(biāo)為(x裹虫,y)的元素坐標(biāo)。但是在使用它時(shí)要注意融击,在編譯期必須要已知圖像的數(shù)據(jù)類(lèi)型筑公,這是因?yàn)?cv::Mat可以存放任意數(shù)據(jù)類(lèi)型的元素。因此at方法的實(shí)現(xiàn)是用模板函數(shù)來(lái)實(shí)現(xiàn)的尊浪。示例是獲取一張CV_8UC3(3通道) 圖片的中心點(diǎn)的像素點(diǎn)的RGB值(注意RGB的排列也是有順序的)
? //創(chuàng)建一張圖片
? ? Mat imagesrc(100,100,CV_8UC3,Scalar(255,0,0));
? ? int row =50;
? ? int col =50;
? ? //圖片上的像素點(diǎn)
? ? imagesrc.at(row,col);
? ? //
? ? imagesrc.at(row,col)[0];//B的值
? ? imagesrc.at(row,col)[1];//G的值
? ? imagesrc.at(row,col)[2];//R的值
CV_8UC1 ? CV_8UC3 ? CV_8UC4
?CV_8? ? ?bit_depth---比特?cái)?shù)---代表8bite,16bites,32bites,64bites---舉個(gè)例子吧- 如果你現(xiàn)在創(chuàng)建了一個(gè)存儲(chǔ)--灰度圖片的Mat對(duì)象,這個(gè)圖像的大小為寬100,高100,那么,現(xiàn)在這張灰度圖片中有10000個(gè)像素點(diǎn)匣屡,它每一個(gè)像素點(diǎn)在內(nèi)存空間所占的空間大小是8bite
? ?S ? 代表---signed int---有符號(hào)整形
? ?U ? 代表--unsigned int--無(wú)符號(hào)整形
? ?F ? ?代表--float---------單精度浮點(diǎn)型
? ?3C ?代表一張圖片的通道數(shù),比如:
? ? ? ? C1 ? 灰度圖片(單通道圖像)
? ? ? ? C3 ?RGB彩色圖像,(3通道圖像)
? ? ? ? C4 ?帶Alph通道的RGB圖像(4通道圖像)
Scalar?
在openCV中表示顏色?
示例??Scalar(B,G,R) ?這邊要注意順序 是BGR
Point?
?表示了由其圖像坐標(biāo) X 和 Y指定的2D點(diǎn)
Point_<int> ? ?就是Point2i,?
Point_<float>?就是Point2f,
Point_<double>就是Point2d。
Size?
表示圖像的width height
Size_<int> ? ?就是Size2i拇涤,也是Size
Size_<float>?就是Size2f捣作。
Rect
表示圖像的 x、y鹅士、width券躁、height,分別為左上角點(diǎn)的坐標(biāo)和矩形的寬和高
關(guān)于 Rect 操作示例
? ? int x =0;
? ? int y =0;
? ? int w =100;
? ? int h =100;
? ? Rect2i rect =Rect2i(x,y,w,h);
? ? //size
? ? rect.size();
? ? //面積
? ? rect.area();
? ? //判斷一個(gè)點(diǎn)是否在矩形內(nèi)
? ? Point2i point(50,50);
? ? bool result = rect.contains(point);
? ? NSLog(@"----%d",result);
? ? //返回左上坐標(biāo)的點(diǎn)
? ? Point2i topLeftPoint =rect.tl();
? ? //(cv::Point2i) topLeftPoint = (x = 0, y = 0)
? ? //返回右下角坐標(biāo)的
?? ?Point2i bottomRightPoint =rect.br();
? ? //(cv::Point2i) bottomRightPoint = (x = 100, y = 100)
? ? //兩個(gè)矩形的交集
? ? Rect2i rect1 =Rect2i(0,0,100,100);
? ? Rect2i rect2 =Rect2i(50,50,100,100);
? ? Rect2i iRect = rect1 & rect2;
? ? //(cv::Rect2i) iRect = (x = 50, y = 50, width = 50, height = 50)
? ? //兩個(gè)矩形的并集
? ? Rect2i asRect = rect1 | rect2;
? ? //(cv::Rect2i) asRect = (x = 0, y = 0, width = 150, height = 150)
? ? //矩形平移
?? ?Point2i changePoint =Point2i(200,200);
? ? Rect2i? rect3 =Rect2i(0,0,100,100);
? ? Rect2i changePointRect = rect3+changePoint;
? ? //(cv::Rect2i) changeRect = (x = 200, y = 200, width = 100, height = 100)
? ? //矩形縮放
? ? Size2i changeSize =Size2i(300,300);
? ? Rect2i? rect4 =Rect2i(0,0,100,100);
? ? Rect2i changeSizeRect = rect4+changeSize;
? ? //(cv::Rect2i) changeSizeRect = (x = 0, y = 0, width = 400, height = 400)