在做圖像處理中,常用的函數接口有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)”的由來。
總結:
不同的實際情況中可能需要用到不同的圖像庫和對應的函數接口,因此經常需要用到這些不同的庫的圖像對象之間的數據的轉換,實際根據情況進行下緩緩即可。
[轉自](https://blog.csdn.net/u012273127/article/details/70311970)