OpenCVの画像データの大きさやビット深度、画像データのポインタなどを管理しているのがIplImage構造体になります。
(OpenCV2.0からはcv:Matクラスというのも登場してきますが、ここではIplImageについて解説したいと思います。)
C言語のBITMAPINFO、.NETのBitmapクラスのようなものです。
OpenCVではこのIplImage構造体をOpenCVの各種関数の引数として渡します。
そこで、IplImage構造体の定義のヘッダファイル【cxtypes.h(OpenCV2.2ではtypes_c.h)】をのぞいてみると、
typedef struct _IplImage { int nSize; /* sizeof(IplImage) */ int ID; /* version (=0)*/ int nChannels; /* Most of OpenCV functions support 1,2,3 or 4 channels */ int alphaChannel; /* Ignored by OpenCV */ int depth; /* Pixel depth in bits: IPL_DEPTH_8U, IPL_DEPTH_8S, IPL_DEPTH_16S, IPL_DEPTH_32S, IPL_DEPTH_32F and IPL_DEPTH_64F are supported. */ char colorModel[4]; /* Ignored by OpenCV */ char channelSeq[4]; /* ditto */ int dataOrder; /* 0 - interleaved color channels, 1 - separate color channels. cvCreateImage can only create interleaved images */ int origin; /* 0 - top-left origin, 1 - bottom-left origin (Windows bitmaps style). */ int align; /* Alignment of image rows (4 or 8). OpenCV ignores it and uses widthStep instead. */ int width; /* Image width in pixels. */ int height; /* Image height in pixels. */ struct _IplROI *roi; /* Image ROI. If NULL, the whole image is selected. */ struct _IplImage *maskROI; /* Must be NULL. */ void *imageId; /* " " */ struct _IplTileInfo *tileInfo; /* " " */ int imageSize; /* Image data size in bytes (==image->height*image->widthStep in case of interleaved data)*/ char *imageData; /* Pointer to aligned image data. */ int widthStep; /* Size of aligned image row in bytes. */ int BorderMode[4]; /* Ignored by OpenCV. */ int BorderConst[4]; /* Ditto. */ char *imageDataOrigin; /* Pointer to very origin of image data (not necessarily aligned) - needed for correct deallocation */ } IplImage;
となっています。
基本的にcvCreateImageもしくはcvLoadImage関数でIplImage構造体のデータを確保するので、IplImageの全てを知らなくても、なんとかなるのですが、主なメンバ変数は以下のとおりです。
nSize | IplImage構造体のサイズ |
nChannels | チャンネル数 1,2,3,4のどれか |
depth | 1画素あたりのビット数 実質使えるのはIPL_DEPTH_8U(符号なし8ビット)と一部でIPL_DEPTH_16S(符号付き16ビット)ぐらい。 24ビットカラー(R,G,B各8ビット)の場合、8ビット、3チャンネル nChannels = 3、depth = IPL_DEPTH_8U とする。 |
origin | 画像データの原点(基準) 0:左上原点(デフォルト) 1:左下原点 originはcvShowImageやcvSobelなどの画像の上下の向きが必要な場合に用いられます。 注)originの値を変えても画像データの並びは変わりません。 |
width | 画像の幅(画素数) |
height | 画像の高さ(画素数) |
imageSize | 画像データのサイズ(バイト数) (= widthStep * height) |
imageData | 画像データへのポインタ |
widthStep | 画像データの幅のバイト数(画素数ではありません。) ビットマップ(*.bmp)データと同様に4バイト単位に調整されています。 |
【補足説明】
- nChannels
OpenCVではチャンネルという概念が登場しますが、これは1画素をいくつの色で表現するか?
を示します。
例えば、一般にRGBカラーの画像は24Bitカラーなどと表現しますが、OpenCV的には
8Bit×3チャンネルと表現します。
- imageData
画像データ(輝度値、画素値)は、このimageDataのポインタを参照する事で輝度値を参照する事が出来ます。
ただし、構造体の宣言を見ても分かるように、imageDataは符号付き8Bitのポインタ(char*)で宣言されているので、符号無し8Bitの256階調で輝度値を参照したい場合は、imageDataのポインタをキャストして参照して下さい。
(例)
IplImage* Src;
・・・
byte* pBuf = (byte*)Src->imageData;また、OpenCVで確保されるimageDataのメモリのアドレスは16バイト境界になるように調整されています。つまり、アドレスが0x09BE0050などのように最下位の値が0となります。
この事からもSSEなどと非常に相性がいいのです。
【IplImageの確保例】
- ファイルから確保する場合
IplImage* src_img = cvLoadImage(“TestImage.bmp”,
CV_LOAD_IMAGE_ANYDEPTH | CV_LOAD_IMAGE_ANYCOLOR);
- 新規に画像データを確保する場合
IplImage* src_img = cvCreateImage(
cvSize(640, 480), IPL_DEPTH_8U, 3);※depthの値は、符号のある/なしを区別するため、数値(8など)を指定せず、下記定数の中から指定すること。
IPL_DEPTH_8U – 符号無し 8 ビット整数
IPL_DEPTH_8S – 符号有り 8 ビット整数
IPL_DEPTH_16U – 符号無し 16 ビット整数
IPL_DEPTH_16S – 符号有り 16 ビット整数
IPL_DEPTH_32S – 符号有り 32 ビット整数
IPL_DEPTH_32F – 単精度浮動小数点数
IPL_DEPTH_64F – 倍精度浮動小数点数
ただし、使い終わったら解放するのもお忘れなく。
cvReleaseImage(&src_img);