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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

opencv的基本数据结构(一)(转)

發布時間:2024/8/26 编程问答 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 opencv的基本数据结构(一)(转) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

從2001年以來,opencv的函數庫一直是基于C接口構建的,因此在opencv1.0版本中,一般使用IplImage的C結構體在內存中存儲圖像,因此,我們在很多較經典的書籍或者開源項目中依然可見IplImage。但是用其存儲圖像的時候必須在退出前將圖像內存手動release掉,即添加語句cvReleaseImage(&IplImage);,否則會造成內存泄漏。Mat類帶來了自動的內存管理,同時它的操作也更加簡單,比如用imshow顯示圖像,imread讀取圖像等等,跟Matlab有點接近。下面是將圖像容器類mat轉化成IplImage結構體的一種方法,最后別忘了cvReleaseImage(&pImg)。

Mat frame,frame1; IplImage* pImg; frame=capture.read(); frame1=frame.clone(); pImg=cvCreateImage(cvSize(frame.cols,frame.rows),8,3); pImg->imageData=(char*)frame1.data;
...

Mat是一個類,它由兩個數據部分組成:矩陣頭和一個指向存儲所有像素值的矩陣的指針。其中矩陣頭包含了矩陣的尺寸、存儲方法、儲存地址等信息,由此可以看出矩陣頭所占的內存很小,通常是一個常數值,而具體存儲所有像素值的矩陣則非常大。因此,在程序中傳遞圖像并創建副本時,大的開銷是由矩陣造成的,而不是信息頭。其實上面給的mat轉IplImage結構體就是一個例子,顯然復制圖像會增加算法的復雜度,降低程序的性能。形象點說,在一個班級里,矩陣頭就相當于存儲了班級里有多少人、男女比多少、平均身高等信息,而矩陣就儲存了班級中所有同學的所有基本信息,每一個同學就相當于是一個像素矩陣中的一個元素,那么根據不同的存儲方法就得到了不同的元素表示方法,顯然矩陣要比矩陣頭復雜得多。

為了解決上述代碼存在的問題。opencv使用了引用計數機制,其思路就是讓每個Mat對象有自己的信息頭,但是共享同一個矩陣。也就是讓矩陣指針指向同一地址,共用一片內存來實現。復制圖像的時候只是復制了矩陣頭的信息和矩陣指針,并不是復制了整個矩陣。例如下面這段代碼:

Mat A,C;//僅創建信息頭部分 A= imread("1.jpg",CV_LOAD_IMAGE_COLOR);//這里為矩陣開辟內存 Mat B(A);//使用拷貝構造函數 C=A;

這段代碼中,A、B和C都是Mat類型,它們都指向同一個也是唯一一個數據矩陣。雖然它們的信息頭不同,但通過任何一個對象所做的改變也會影響其它對象。而通過clone()或者copyTo()來復制一個圖像,就包括了矩陣本身,也因此,改變復制對象的內容并不會改變源矩陣,例如frame1顯然是復制frame,因此對frame1的操作并不改變frame。

Mat的常見屬性

屬性說明
datauchar型的指針。Mat類分為了兩個部分:矩陣頭和指向矩陣數據部分的指針,data就是指向矩陣數據的指針。
dims矩陣的維度,例如5*6矩陣是二維矩陣,則dims=2,三維矩陣dims=3.
rows矩陣的行數
cols矩陣的列數
size矩陣的大小,size(cols,rows)
channels()矩陣元素擁有的通道數,例如常見的彩色圖像,每一個像素由RGB三個通道組成
type()表示了矩陣中元素的類型以及矩陣的通道個數,它是一系列的預定義的常量,其命名規則為CV_(位數)+(數據類型)+(通道數)如:,CV_8UC3
depth()矩陣中元素的一個通道的數據類型,這個值和type是相關的。例如 type為 CV_8UC3,一個3通道的16位的有符號整數。那么,depth則是CV_8UC
elemSize()矩陣一個元素占用的字節數(不區分通道,即多個通道的總和)
elemSize1()矩陣一個元素每個通道占用的字節數(區分通道,單個通道的值)
flags一個int型數字,保存了許多有用的信息,flags說明;

創建Mat的方式:

?

1、Mat M?
創建一個矩陣頭,沒有數據。?
2、Mat M(2,2,CV_8UC3,Scalar(0,0,1));?
2*2大小的矩陣,每個元素為3通道8位無符號整數,如下:?

0 0 1 0 0 1?
0 0 1 0 0 1?
3、Mat M(2,2,CV_8UC1,Scalar(10));?
與上面類似:?
10 10?
10 10?
4、Mat M(2,2,CV_8UC1,Scalar::all(0));
5、以逗號分隔符初始化賦值:Mat M = (Mat_(3,3) << 1,2,3,4,5,6,7,8,9);?
6、為已經存在的IplImage指針創建信息頭,例如:

IplImage* img=cvLoadImage("1.jpg",1); Mat mtx(img);//轉換IplImage*為Mat

7、利用create()函數

Mat M;
M.create(4,4,CV_8UC(2)); cout<<"M="M<<endl;

但是這種方法不能為矩陣設初值,只是在改變尺寸時重新為矩陣數據開辟內存而已。

8、Mat還有一些matlab式函數用來創建和初始化矩陣:?
Mat E = Mat::eye(4,4,CV_64F); //單位矩陣
Mat Z = Mat::zeros(4,4,CV_32F); //0矩陣
Mat O = Mat::ones(4,4,CV_8UC1); //1矩陣
9、為已經存在的對象創建新的信息頭

Mat E=Mat::eye(4,4,CV_64F); Mat Row=E.row(1).clone(); cout<<Row<<endl;

?

轉載于:https://www.cnblogs.com/cvtoEyes/p/8502602.html

與50位技術專家面對面20年技術見證,附贈技術全景圖

總結

以上是生活随笔為你收集整理的opencv的基本数据结构(一)(转)的全部內容,希望文章能夠幫你解決所遇到的問題。

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