當(dāng)前位置:首頁 > 智能硬件 > 人工智能AI
[導(dǎo)讀]   opencv中常見的與圖像操作有關(guān)的數(shù)據(jù)容器有Mat,cvMat和IplImage,這三種類型都可以代表和顯示圖像,但是,Mat類型側(cè)重于計算,數(shù)學(xué)性較高,openCV對Mat類型的計算也進

  opencv中常見的與圖像操作有關(guān)的數(shù)據(jù)容器有Mat,cvMat和IplImage,這三種類型都可以代表和顯示圖像,但是,Mat類型側(cè)重于計算,數(shù)學(xué)性較高,openCV對Mat類型的計算也進行了優(yōu)化。而CvMat和IplImage類型更側(cè)重于“圖像”,opencv對其中的圖像操作(縮放、單通道提取、圖像閾值操作等)進行了優(yōu)化。在opencv2.0之前,opencv是完全用C實現(xiàn)的,但是,IplImage類型與CvMat類型的關(guān)系類似于面向?qū)ο笾械睦^承關(guān)系。實際上,CvMat之上還有一個更抽象的基類----CvArr,這在源代碼中會常見。

  1. IplImage

  opencv中的圖像信息頭,該結(jié)構(gòu)體定義: typedef struct _IplImage

  {

  int nSize; /* IplImage大小 */

  int ID; /* 版本 (=0)*/

  int nChannels; /* 大多數(shù)OPENCV函數(shù)支持1,2,3 或 4 個通道 */

  int alphaChannel; /* 被OpenCV忽略 */

  int depth; /* 像素的位深度: IPL_DEPTH_8U, IPL_DEPTH_8S, IPL_DEPTH_16U,

  IPL_DEPTH_16S, IPL_DEPTH_32S, IPL_DEPTH_32F and IPL_DEPTH_64F 可支持 */

  char colorModel[4]; /* 被OpenCV忽略 */

  char channelSeq[4]; /* 被OpenCV忽略 */

  int dataOrder; /* 0 - 交叉存取顏色通道, 1 - 分開的顏色通道。 cvCreateImage只能創(chuàng)建交叉存取圖像 */

  int origin; /* 0 - 頂—左結(jié)構(gòu),1 - 底—左結(jié)構(gòu) (Windows bitmaps 風(fēng)格) */

  int align; /* 圖像行排列 (4 or 8)。 OpenCV 忽略它,使用 widthStep 代替 */

  int width; /* 圖像寬像素數(shù) */

  int height; /* 圖像高像素數(shù)*/

  struct _IplROI *roi; /* 圖像感興趣區(qū)域。 當(dāng)該值非空只對該區(qū)域進行處理 */

  struct _IplImage *maskROI; /* 在 OpenCV中必須置NULL */

  void *imageId; /* 同上*/

  struct _IplTIleInfo *TIleInfo; /*同上*/

  int imageSize; /* 圖像數(shù)據(jù)大?。ㄔ诮徊娲嫒「袷较耰mageSize=image-》height*image-》widthStep),單位字節(jié)*/

  char *imageData; /* 指向排列的圖像數(shù)據(jù) */

  int widthStep; /* 排列的圖像行大小,以字節(jié)為單位 */

  int BorderMode[4]; /* 邊際結(jié)束模式, 被OpenCV忽略 */

  int BorderConst[4]; /* 同上 */

  char *imageDataOrigin; /* 指針指向一個不同的圖像數(shù)據(jù)結(jié)構(gòu)(不是必須排列的),是為了糾正圖像內(nèi)存分配準(zhǔn)備的 */

  } IplImage;

  dataOrder中的兩個取值:交叉存取顏色通道是顏色數(shù)據(jù)排列將會是BGRBGR.。.的交錯排列。分開的顏色通道是有幾個顏色通道就分幾個顏色平面存儲。roi是IplROI結(jié)構(gòu)體,該結(jié)構(gòu)體包含了xOffset,yOffset,height,width,coi成員變量,其中xOffset,yOffset是x,y坐標(biāo),coi代表channel of interest(感興趣的通道),非0的時候才有效。訪問圖像中的數(shù)據(jù)元素,分間接存儲和直接存儲,當(dāng)圖像元素為浮點型時,(uchar *) 改為 (float *):

  /*間接存取*/

  IplImage* img=cvLoadImage(“lena.jpg”, 1);

  CvScalar s; /*sizeof(s) == img-》nChannels*/

  s=cvGet2D(img,i,j); /*get the (i,j) pixel value*/

  cvSet2D(img,i,j,s); /*set the (i,j) pixel value*/

  /*宏操作*/

  IplImage* img; //malloc memory by cvLoadImage or cvCreateImage

  for(int row = 0; row 《 img-》height; row++)

  {

  for (int col = 0; col 《 img-》width; col++)

  {

  b = CV_IMAGE_ELEM(img, UCHAR, row, col * img-》nChannels + 0);

  g = CV_IMAGE_ELEM(img, UCHAR, row, col * img-》nChannels + 1);

  r = CV_IMAGE_ELEM(img, UCHAR, row, col * img-》nChannels + 2);

  }

  }

  /*直接存取*/

  IplImage* img; //malloc memory by cvLoadImage or cvCreateImage

  uchar b, g, r; // 3 channels

  for(int row = 0; row 《 img-》height; row++)

  {

  for (int col = 0; col 《 img-》width; col++)

  {

  b = ((uchar *)(img-》imageData + row * img-》widthStep))[col * img-》nChannels + 0];

  g = ((uchar *)(img-》imageData + row * img-》widthStep))[col * img-》nChannels + 1];

  r = ((uchar *)(img-》imageData + row * img-》widthStep))[col * img-》nChannels + 2];

  }

  }

  初始化使用IplImage *,是一個指向結(jié)構(gòu)體IplImage的指針:

  IplImage * cvLoadImage(const char * filename, int iscolor CV_DEFAULT(CV_LOAD_IMAGE_COLOR)); //load images from specified image

  IplImage * cvCreateImage(CvSize size, int depth, int channels); //allocate memory

  2.CvMat

  首先,我們需要知道,第一,在OpenCV中沒有向量(vector)結(jié)構(gòu)。任何時候需要向量,都只需要一個列矩陣(如果需要一個轉(zhuǎn)置或者共軛向量,則需要一個行矩陣)。第二,OpenCV矩陣的概念與我們在線性代數(shù)課上學(xué)習(xí)的概念相比,更抽象,尤其是矩陣的元素,并非只能取簡單的數(shù)值類型,可以是多通道的值。CvMat 的結(jié)構(gòu):

  typedef struct CvMat

  {

  int type;

  int step; /*用字節(jié)表示行數(shù)據(jù)長度*/

  int* refcount; /*內(nèi)部訪問*/

  union {

  uchar* ptr;

  short* s;

  int* i;

  float* fl;

  double* db;

  } data; /*數(shù)據(jù)指針*/

  union {

  int rows;

  int height;

  };

  union {

  int cols;

  int width;

  };

  } CvMat; /*矩陣結(jié)構(gòu)頭*/

  創(chuàng)建CvMat數(shù)據(jù):

  CvMat * cvCreateMat(int rows, int cols, int type); /*創(chuàng)建矩陣頭并分配內(nèi)存*/

  CV_INLine CvMat cvMat((int rows, int cols, int type, void* data CV_DEFAULT); /*用已有數(shù)據(jù)data初始化矩陣*/

  CvMat * cvInitMatHeader(CvMat * mat, int rows, int cols, int type, void * data CV_DEFAULT(NULL), int step CV_DEFAULT(CV_AUTOSTEP)); /*(用已有數(shù)據(jù)data創(chuàng)建矩陣頭)*/

  對矩陣數(shù)據(jù)進行訪問:

  /*間接訪問*/

  /*訪問CV_32F1和CV_64FC1*/

  cvmSet( CvMat* mat, int row, int col, double value);

  cvmGet( const CvMat* mat, int row, int col );

  /*訪問多通道或者其他數(shù)據(jù)類型: scalar的大小為圖像的通道值*/

  CvScalar cvGet2D(const CvArr * arr, int idx0, int idx1); //CvArr只作為函數(shù)的形參void cvSet2D(CvArr* arr, int idx0, int idx1, CvScalar value);

  /*直接訪問: 取決于數(shù)組的數(shù)據(jù)類型*/

  /*CV_32FC1*/

  CvMat * cvmat = cvCreateMat(4, 4, CV_32FC1);

  cvmat-》data.fl[row * cvmat-》cols + col] = (float)3.0;

  /*CV_64FC1*/

  CvMat * cvmat = cvCreateMat(4, 4, CV_64FC1);

  cvmat-》data.db[row * cvmat-》cols + col] = 3.0;

  /*一般對于單通道*/

  CvMat * cvmat = cvCreateMat(4, 4, CV_64FC1);

  CV_MAT_ELEM(*cvmat, double, row, col) = 3.0; /*double是根據(jù)數(shù)組的數(shù)據(jù)類型傳入,這個宏不能處理多通道*/

  /*一般對于多通道*/

  if (CV_MAT_DEPTH(cvmat-》type) == CV_32F)

  CV_MAT_ELEM_CN(*cvmat, float, row, col * CV_MAT_CN(cvmat-》type) + ch) = (float)3.0; // ch為通道值

  if (CV_MAT_DEPTH(cvmat-》type) == CV_64F)

  CV_MAT_ELEM_CN(*cvmat, double, row, col * CV_MAT_CN(cvmat-》type) + ch) = 3.0; // ch為通道值

  /*多通道數(shù)組*/

  /*3通道*/

  for (int row = 0; row 《 cvmat-》rows; row++)

  {

  p = cvmat -》data.fl + row * (cvmat-》step / 4);

  for (int col = 0; col 《 cvmat-》cols; col++)

  {

  *p = (float) row + col;

  *(p+1) = (float)row + col + 1;

  *(p+2) = (float)row + col + 2;

  p += 3;

  }

  }

  /*2通道*/

  CvMat * vector = cvCreateMat(1,3, CV_32SC2);CV_MAT_ELEM(*vector, CvPoint, 0, 0) = cvPoint(100,100);

  /*4通道*/

  CvMat * vector = cvCreateMat(1,3, CV_64FC4);CV_MAT_ELEM(*vector, CvScalar, 0, 0) = CvScalar(0, 0, 0, 0);

  復(fù)制矩陣操作:

  /*復(fù)制矩陣*/

  CvMat* M1 = cvCreateMat(4,4,CV_32FC1);

  CvMat* M2;

  M2=cvCloneMat(M1);

  3.Mat

  Mat是opencv2.0推出的處理圖像的新的數(shù)據(jù)結(jié)構(gòu),現(xiàn)在越來越有趨勢取代之前的cvMat和lplImage,相比之下Mat最大的好處就是能夠更加方便的進行內(nèi)存管理,不再需要程序員手動管理內(nèi)存的釋放。opencv2.3中提到Mat是一個多維的密集數(shù)據(jù)數(shù)組,可以用來處理向量和矩陣、圖像、直方圖等等常見的多維數(shù)據(jù)。

  class CV_EXPORTS Mat

  {

  public:

  /*.。很多方法。.*/

  /*.。..。..。..。.*/

  int flags;(Note :目前還不知道flags做什么用的)

  int dims; /*數(shù)據(jù)的維數(shù)*/

  int rows,cols; /*行和列的數(shù)量;數(shù)組超過2維時為(-1,-1)*/

  uchar *data; /*指向數(shù)據(jù)*/

  int * refcount; /*指針的引用計數(shù)器; 陣列指向用戶分配的數(shù)據(jù)時,指針為 NULL

  /* 其他成員 */

  。..

  };

  從以上結(jié)構(gòu)體可以看出Mat也是一個矩陣頭,默認(rèn)不分配內(nèi)存,只是指向一塊內(nèi)存(注意讀寫保護)。初始化使用create函數(shù)或者Mat構(gòu)造函數(shù),以下整理自opencv2.3.1 Manual:

  Mat(nrows, ncols, type, fillValue]);

  M.create(nrows, ncols, type);

  例子:

  Mat M(7,7,CV_32FC2,Scalar(1,3)); /*創(chuàng)建復(fù)數(shù)矩陣1+3j*/

  M.create(100, 60, CV_8UC(15)); /*創(chuàng)建15個通道的8bit的矩陣*/

  /*創(chuàng)建100*100*100的8位數(shù)組*/

  int sz[] = {100, 100, 100};

  Mat bigCube(3, sz, CV_8U, Scalar:all(0));

  /*現(xiàn)成數(shù)組*/

  double m[3][3] = {{a, b, c}, {d, e, f}, {g, h, i}};

  Mat M = Mat(3, 3, CV_64F, m).inv();

  /*圖像數(shù)據(jù)*/

  Mat img(Size(320,240),CV_8UC3);

  Mat img(height, width, CV_8UC3, pixels, step); /*const unsigned char* pixels,int width, int height, int step*/

  /*使用現(xiàn)成圖像初始化Mat*/

  IplImage* img = cvLoadImage(“greatwave.jpg”, 1);

  Mat mtx(img,0); // convert IplImage* -》 Mat; /*不復(fù)制數(shù)據(jù),只創(chuàng)建一個數(shù)據(jù)頭*/

  訪問Mat的數(shù)據(jù)元素:

  /*對某行進行訪問*/

  Mat M;

  M.row(3) = M.row(3) + M.row(5) * 3; /*第5行擴大三倍加到第3行*/

  /*對某列進行復(fù)制操作*/

  Mat M1 = M.col(1);

  M.col(7).copyTo(M1); /*第7列復(fù)制給第1列*/

  /*對某個元素的訪問*/

  Mat M;

  M.at《double》(i,j); /*double*/

  M.at(uchar)(i,j); /*CV_8UC1*/

  Vec3i bgr1 = M.at(Vec3b)(i,j) /*CV_8UC3*/

  Vec3s bgr2 = M.at(Vec3s)(i,j) /*CV_8SC3*/

  Vec3w bgr3 = M.at(Vec3w)(i,j) /*CV_16UC3*/

  /*遍歷整個二維數(shù)組*/

  double sum = 0.0f;

  for(int row = 0; row 《 M.rows; row++)

  {

  const double * Mi = M.ptr《double》(row);

  for (int col = 0; col 《 M.cols; col++)

  sum += std::max(Mi[j], 0.);

  }

  /*STL iterator*/

  double sum=0;

  MatConsTIterator《double》 it = M.begin《double》(), it_end = M.end《double》();

  for(; it != it_end; ++it)

  sum += std::max(*it, 0.);

  Mat可進行Matlab風(fēng)格的矩陣操作,如初始化的時候可以用iniTIalizers,zeros(), ones(), eye()。 除以上內(nèi)容之外,Mat還有有3個重要的方法:

  Mat mat = imread(const String* filename); // 讀取圖像imshow(const string frameName, InputArray mat); // 顯示圖像imwrite (const string& filename, InputArray img); //儲存圖像

  CvMat, Mat, IplImage之間的互相轉(zhuǎn)換

  IpIImage -》 CvMat

  /*cvGetMat*/

  CvMat matheader;

  CvMat * mat = cvGetMat(img, &matheader);

  /*cvConvert*/

  CvMat * mat = cvCreateMat(img-》height, img-》width, CV_64FC3);

  cvConvert(img, mat)

  IplImage -》 Mat

  Mat::Mat(const IplImage* img, bool copyData=false);/*default copyData=false,與原來的IplImage共享數(shù)據(jù),只是創(chuàng)建一個矩陣頭*/

  例子:

  IplImage* iplImg = cvLoadImage(“greatwave.jpg”, 1);

  Mat mtx(iplImg); /* IplImage * -》 Mat,共享數(shù)據(jù); or : Mat mtx = iplImg;*/

  Mat -》 IplImage

  Mat M

  IplImage iplimage = M; /*只創(chuàng)建圖像頭,不復(fù)制數(shù)據(jù)*/

  CvMat -》 Mat

  Mat::Mat(const CvMat* m, bool copyData=false); /*類似IplImage -》 Mat,可選擇是否復(fù)制數(shù)據(jù)*/

  Mat -》 CvMat

  例子(假設(shè)Mat類型的imgMat圖像數(shù)據(jù)存在):

  CvMat cvMat = imgMat;/*Mat -》 CvMat, 類似轉(zhuǎn)換到IplImage,不復(fù)制數(shù)據(jù)只創(chuàng)建矩陣頭

本站聲明: 本文章由作者或相關(guān)機構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點,本站亦不保證或承諾內(nèi)容真實性等。需要轉(zhuǎn)載請聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請及時聯(lián)系本站刪除。
換一批
延伸閱讀

9月2日消息,不造車的華為或?qū)⒋呱龈蟮莫毥谦F公司,隨著阿維塔和賽力斯的入局,華為引望愈發(fā)顯得引人矚目。

關(guān)鍵字: 阿維塔 塞力斯 華為

加利福尼亞州圣克拉拉縣2024年8月30日 /美通社/ -- 數(shù)字化轉(zhuǎn)型技術(shù)解決方案公司Trianz今天宣布,該公司與Amazon Web Services (AWS)簽訂了...

關(guān)鍵字: AWS AN BSP 數(shù)字化

倫敦2024年8月29日 /美通社/ -- 英國汽車技術(shù)公司SODA.Auto推出其旗艦產(chǎn)品SODA V,這是全球首款涵蓋汽車工程師從創(chuàng)意到認(rèn)證的所有需求的工具,可用于創(chuàng)建軟件定義汽車。 SODA V工具的開發(fā)耗時1.5...

關(guān)鍵字: 汽車 人工智能 智能驅(qū)動 BSP

北京2024年8月28日 /美通社/ -- 越來越多用戶希望企業(yè)業(yè)務(wù)能7×24不間斷運行,同時企業(yè)卻面臨越來越多業(yè)務(wù)中斷的風(fēng)險,如企業(yè)系統(tǒng)復(fù)雜性的增加,頻繁的功能更新和發(fā)布等。如何確保業(yè)務(wù)連續(xù)性,提升韌性,成...

關(guān)鍵字: 亞馬遜 解密 控制平面 BSP

8月30日消息,據(jù)媒體報道,騰訊和網(wǎng)易近期正在縮減他們對日本游戲市場的投資。

關(guān)鍵字: 騰訊 編碼器 CPU

8月28日消息,今天上午,2024中國國際大數(shù)據(jù)產(chǎn)業(yè)博覽會開幕式在貴陽舉行,華為董事、質(zhì)量流程IT總裁陶景文發(fā)表了演講。

關(guān)鍵字: 華為 12nm EDA 半導(dǎo)體

8月28日消息,在2024中國國際大數(shù)據(jù)產(chǎn)業(yè)博覽會上,華為常務(wù)董事、華為云CEO張平安發(fā)表演講稱,數(shù)字世界的話語權(quán)最終是由生態(tài)的繁榮決定的。

關(guān)鍵字: 華為 12nm 手機 衛(wèi)星通信

要點: 有效應(yīng)對環(huán)境變化,經(jīng)營業(yè)績穩(wěn)中有升 落實提質(zhì)增效舉措,毛利潤率延續(xù)升勢 戰(zhàn)略布局成效顯著,戰(zhàn)新業(yè)務(wù)引領(lǐng)增長 以科技創(chuàng)新為引領(lǐng),提升企業(yè)核心競爭力 堅持高質(zhì)量發(fā)展策略,塑強核心競爭優(yōu)勢...

關(guān)鍵字: 通信 BSP 電信運營商 數(shù)字經(jīng)濟

北京2024年8月27日 /美通社/ -- 8月21日,由中央廣播電視總臺與中國電影電視技術(shù)學(xué)會聯(lián)合牽頭組建的NVI技術(shù)創(chuàng)新聯(lián)盟在BIRTV2024超高清全產(chǎn)業(yè)鏈發(fā)展研討會上宣布正式成立。 活動現(xiàn)場 NVI技術(shù)創(chuàng)新聯(lián)...

關(guān)鍵字: VI 傳輸協(xié)議 音頻 BSP

北京2024年8月27日 /美通社/ -- 在8月23日舉辦的2024年長三角生態(tài)綠色一體化發(fā)展示范區(qū)聯(lián)合招商會上,軟通動力信息技術(shù)(集團)股份有限公司(以下簡稱"軟通動力")與長三角投資(上海)有限...

關(guān)鍵字: BSP 信息技術(shù)
關(guān)閉
關(guān)閉