本专题是学习Algorithms for Image Processing and Computer Vision的笔记。
AIPCV是书名的缩写。
使用OpenCV时,需要了解的关键细节是数据结构的如何实现。因此,吧OpenCV和AIPCV连接起来的主要工作在于提供一种两个系统之间转换图像数据结构的方法。对于灰阶单通道的图像来说,这一点很简单,对于彩色图像来说,则更复杂。
AIPCV库中的基本图像数据结构由两个数据结构组成
一个是表头信息,另一个表示图像。
图像命名为image,由两个指针组成,一个纸箱头信息,一个纸箱存储的数据。
图像的结构体表示法如下:
struct image { struct header *info; // Pointer to header unsigned char **data; // Pointer tp pixels };头信息表示如下:
struct header { int nr, nc; int oi, oj; };其中nr表示图像的行数,nc表示图像的列数,分别等同于IplImage->height和IplImage->width
oi和oj指定了图像的原点,只有在极少数情况下使用,比如还原,在OpenCV中没有对应的字段。
怎样实现AIPCV和OpenCV之间转换呢?
OpenCV转换成AIPCV
IMAGE fromOpenCV (IplImage *x) { IMAGE img; //定义AIPCV类型图像 int color=0, i=0; int k=0, j=0; CvScalar s; if ((x->depth==IPL_DEPTH_8U) &&(x->nChannels==1)) // Grey image img = newimage (x->height, x->width); //新建一幅图像 else if ((x->depth==8) && (x->nChannels==3)) //Color { color = 1; img = newimage (x->height, x->width); } else return 0; for (i=0; i<x->height; i++) { for (j=0; j<x->width; j++) { s = cvGet2D (x, i, j); if (color) k= (unsigned char) ((s.val[0]+s.val[1]+s.val[2])/3); else k = (unsigned char)(s.val[0]); img->data[i][j] = k; } } return img; }其中newimage表示新建一幅图像。具体如下:
struct image *newimage (int nr, int nc) { struct image *x; /* New image */ int i; unsigned char *p; if (nr < 0 || nc < 0) { printf ("Error: Bad image size (%d,%d)\n", nr, nc); return 0; } /* Allocate the image structure */ x = (struct image *) malloc( sizeof (struct image) ); if (!x) { printf ("Out of storage in NEWIMAGE.\n"); return 0; } /* Allocate and initialize the header */ x->info = (struct header *)malloc( sizeof(struct header) ); if (!(x->info)) { printf ("Out of storage in NEWIMAGE.\n"); return 0; } x->info->nr = nr; x->info->nc = nc; x->info->oi = x->info->oj = 0; /* Allocate the pixel array */ x->data = (unsigned char **)malloc(sizeof(unsigned char *)*nr); /* Pointers to rows */ if (!(x->data)) { printf ("Out of storage in NEWIMAGE.\n"); return 0; } x->data[0] = (unsigned char *)malloc (nr*nc); p = x->data[0]; if (x->data[0]==0) { printf ("Out of storage. Newimage \n"); exit(1); } for (i=1; i<nr; i++) { x->data[i] = (p+i*nc); } return x; }
IplImage *toOpenCV (IMAGE x) { IplImage *img; int i=0, j=0; CvScalar s; img=cvCreateImage(cvSize(x->info->nc,x->info->nr),8, 1); for (i=0; i<x->info->nr; i++) { for (j=0; j<x->info->nc; j++) { s.val[0] = x->data[i][j]; cvSet2D (img, i,j,s); } } return img; }很好理解。