OpenCV中Mat,影象二維指標和CxImage類的轉換
阿新 • • 發佈:2019-02-15
在做影象處理中,常用的函式介面有Opencv中的Mat影象類,有時候需要直接用二維指標開闢記憶體直接儲存影象資料,有時候需要用到CxImage類儲存影象。本文主要是總結下這三類儲存方式之間的影象資料的轉換和相應的對應關係。
一、OpenCV的Mat類到影象二值指標的轉換
以下為函式程式碼:
unsigned char** MatTopImgData(Mat img)
{
//獲取影象引數
int row = img.rows;
int col = img.cols;
int band = img.channels;
//定義影象二值指標
unsigned char** pImgdata = new unsigned char*[band];
for(int i=0;i<band;i++)
pImgdata[i] = new unsigned char[row*col];
for(int i=0;i<row;i++) //行數--高度
{
unsigned char* data = img.ptr<unsigned char>(i); //指向第i行的資料
for(int j=0;j<col;j++) //列數 -- 寬度
{
for (int m=0;m<band;m++) //將各個波段的資料存入陣列
pImgdata[m][i*col+j] = data[j*band+m];
}
}
return pImgdata;
}
需要注意的是:(1)在Mat類中,影象資料的儲存方式是BGR形式,這樣得到的二維指標的資料儲存順序則為BGR形式。(2)在Mat類中影象無論是灰度圖還是RGB圖都是以以為指標的形式儲存的,所以在讀取每個資料時,先找到每行資料的首地址,再順序讀取每行資料的BGR的灰度值。(3)在Mat類中的row為行數,對應平時所說的影象的高度,col為列數對用影象的寬度。
二、影象二值指標到OpenCV的Mat類的轉換
以下為函式程式碼:
Mat ImgData(unsigned char** pImgdata, int width, int height, int band)
{
Mat Img;
if(band == 1) //灰度圖
Img.create(height, width, CV_8UC1);
else //彩色圖
Img.create(height, width, CV_8UC3);
for(int i=0;i<height;i++) //行數--高度
{
unsigned char* data = Img.ptr<unsigned char>(i); //指向第i行的資料
for(int j=0;j<width;j++) //列數 -- 寬度
{
for(int m=0;m<band;m++) //將各個波段的資料存入陣列
data[j*band+m]=pImgdata[m][i*width+j];
}
}
return Img;
}
三、CxImage類到影象二維指標的轉換
以下為函式程式碼:
unsigned char** CxImageToPimgdata(CxImage Image)
{
int width = Image.GetWidth();
int height = Image.GetHeight();
RGBQUAD rgbdata;
unsigned char** pImgdata = new unsigned char*[3];
for(int m=0;m<3;m++)
pImgdata[m] = new unsigned char[width*height];
for(int i = 0; i < width; i++)
{
for(int j = 0; j < height; j++)
{
//獲取主視窗圖片每一個畫素的rgb資料
rgbdata = Image.GetPixelColor(i, (height-j-1), true);
pImgdata[0][j*width + i] = rgbdata.rgbRed;
pImgdata[1][j*width + i] = rgbdata.rgbGreen;
pImgdata[2][j*width + i] = rgbdata.rgbBlue;
}
}
return pImgdata;
}
需要注意的是:CxImage讀取影象資料後圖像的原點是在影象的左下角,與我們的傳統的影象資料原點為左上角相反,所以在讀取影象時”(height-j-1)”的由來。
總結:
不同的實際情況中可能需要用到不同的影象庫和對應的函式介面,因此經常需要用到這些不同的庫的影象物件之間的資料的轉換,實際根據情況進行下緩緩即可。