CvPoint结构体
typedef struct CvPoint
{
int x; /* x坐标,通常指2D图像中的列,通常从0开始 */
int y; /* y坐标,通常指2D图像中的行,通常从0开始 */
}
CvPoint;
IplImage结构体(列出几个关键项)
typedef struct _IplImage
{
...
int nChannels; /* Most of OpenCV functions support 1,2,3 or 4 channels */
...
int depth; /* pixel depth in bits: IPL_DEPTH_8U, IPL_DEPTH_8S, IPL_DEPTH_16U,
IPL_DEPTH_16S, IPL_DEPTH_32S, IPL_DEPTH_32F and IPL_DEPTH_64F are supported */
...
int width; /* image width in pixels */
int height; /* image height in pixels */
...
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 */
...
}
IplImage;
图像中各个像素点的颜色值存储在imageData指向的一片连续的内存中,可看成一个一维数组。
图像数据采用interleaved的方式存储,如果图像的色彩空间是RGB空间的话,则该片内存中的数据按照BGR的顺序排列。
以一张m行n列,depth为IPL_DEPTH_8U, nChannels为3的RGB彩色图像为例,其在内存中的存储方式如下:
像素(0,0)B, 像素(0,0)G, 像素(0,0)R, 像素(0,1)B, 像素(0,1)G, 像素(0,1)R ... 像素(0,n-1)B, 像素(0,n-1)G, 像素(0,n-1)R, {填充字节},
...
像素(m-1,0)B, 像素(m-1,0)G, 像素(m-1,0)R, 像素(m-1,1)B, 像素(m-1,1)G,像素(m-1,1)R ... 像素(m-1,n-1)B, 像素(m-1,n-1)G, 像素(m-1,n-1)R, {填充字节}
可以注意到每一行除了像素的颜色值之外,还有一些填充字节。这是因为在IplImage的定义中,widthStep必须是4的倍数;也就是说widthStep并不是等于width*nChannels,而是等于最接近width*nChannels的4的倍数。(个人猜想,这个是为了方便32bit的位对齐所做的约定)。
操作图像数据的几种常用方式(以下都假定图像img的depth为IPL_DEPTH_8U,nChannels为3,并且都以取得i行,j列像素的指针为例):
1. imageData指针的位移
char *ptr = img.imageData + img.widthStep*i+j*3;
ptr[0]就是B,ptr[1]就是G,ptr[2]就是R
2. CV_IMAGE_ELEM宏
char *ptr = &CV_IMAGE_ELEM(&img,char,i,j*3);
ptr[0]就是B,ptr[1]就是G,ptr[2]就是R